diff --git a/Documentation/spi/Makefile b/Documentation/spi/Makefile
index a5b03c8..6155d94 100644
--- a/Documentation/spi/Makefile
+++ b/Documentation/spi/Makefile
@@ -1,6 +1,7 @@
 # kbuild trick to avoid linker error. Can be omitted if a module is built.
 obj- := dummy.o
 
+CC = $(CROSS_COMPILE)gcc
 # List of programs to build
 hostprogs-y := spidev_test spidev_fdx
 
diff --git a/Makefile b/Makefile
index 17bfe08..9ca7825 100644
--- a/Makefile
+++ b/Makefile
@@ -1670,3 +1670,16 @@ FORCE:
 # Declare the contents of the .PHONY variable as phony.  We keep that
 # information in a variable se we can use it in if_changed and friends.
 .PHONY: $(PHONY)
+
+pub:
+	cp arch/arm/boot/uImage /tftpboot/
+
+m68:
+	m68k-uclinux-objcopy vmlinux -O binary uc.bin
+	mv uc.bin /tftpboot/
+
+opub:
+	cp arch/arm/boot/Image .
+	gzip -f -9 Image
+	mkimage -A arm -O linux -T kernel -C gzip -a 40008000 -e 40008000 -d Image.gz uImage
+	cp uImage /tftpboot/
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9722f8b..71db83f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -199,6 +199,14 @@ choice
 	prompt "ARM system type"
 	default ARCH_VERSATILE
 
+config ARCH_ASPEED
+	bool "ASPEED AST Family"
+	select ARM_AMBA
+	select PLAT_ASPEED
+        select GENERIC_GPIO
+        select ARCH_REQUIRE_GPIOLIB
+
+
 config ARCH_AAEC2000
 	bool "Agilent AAEC-2000 based"
 	select ARM_AMBA
@@ -551,6 +559,8 @@ config ARCH_MSM
 
 endchoice
 
+source "arch/arm/mach-aspeed/Kconfig"
+
 source "arch/arm/mach-clps711x/Kconfig"
 
 source "arch/arm/mach-ep93xx/Kconfig"
@@ -637,6 +647,9 @@ config PLAT_IOP
 config PLAT_ORION
 	bool
 
+config PLAT_ASPEED
+	bool
+
 source arch/arm/mm/Kconfig
 
 config IWMMXT
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index bd6e281..b039927 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -144,6 +144,8 @@ endif
  machine-$(CONFIG_ARCH_MSM)	   := msm
  machine-$(CONFIG_ARCH_LOKI)       := loki
  machine-$(CONFIG_ARCH_MV78XX0)    := mv78xx0
+ machine-$(CONFIG_ARCH_ASPEED)	   := aspeed
+    plat-$(CONFIG_PLAT_ASPEED)     := aspeed
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/configs/ast2300_ast1070_defconfig b/arch/arm/configs/ast2300_ast1070_defconfig
new file mode 100644
index 0000000..2285e61
--- /dev/null
+++ b/arch/arm/configs/ast2300_ast1070_defconfig
@@ -0,0 +1,1037 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28.9
+# Fri Nov  1 16:40:08 2013
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_ARCH_ASPEED=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+CONFIG_IRMP=y
+# CONFIG_PCEXT is not set
+# CONFIG_REMOTEFX is not set
+# CONFIG_ARCH_AST1100 is not set
+# CONFIG_ARCH_AST2100 is not set
+# CONFIG_ARCH_AST2200 is not set
+CONFIG_ARCH_AST2300=y
+# CONFIG_ARCH_AST2400 is not set
+# CONFIG_ARCH_AST2500 is not set
+
+#
+# FLASH Chip Select
+#
+CONFIG_AST_CS0_NOR=y
+# CONFIG_AST_CS0_NAND is not set
+# CONFIG_AST_CS0_SPI is not set
+# CONFIG_AST_CS0_NONE is not set
+CONFIG_AST_CS1_NOR=y
+# CONFIG_AST_CS1_NAND is not set
+# CONFIG_AST_CS1_SPI is not set
+# CONFIG_AST_CS1_NONE is not set
+CONFIG_AST_CS2_NOR=y
+# CONFIG_AST_CS2_NAND is not set
+# CONFIG_AST_CS2_SPI is not set
+# CONFIG_AST_CS2_NONE is not set
+CONFIG_AST_CS3_NOR=y
+# CONFIG_AST_CS3_NAND is not set
+# CONFIG_AST_CS3_SPI is not set
+# CONFIG_AST_CS3_NONE is not set
+CONFIG_AST_CS4_NOR=y
+# CONFIG_AST_CS4_NAND is not set
+# CONFIG_AST_CS4_SPI is not set
+# CONFIG_AST_CS4_NONE is not set
+CONFIG_ARCH_AST1070=y
+CONFIG_AST1070_NR=1
+# CONFIG_AST_LPC_PLUS is not set
+CONFIG_AST_LPC=y
+# CONFIG_AST_SCU_LOCK is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+CONFIG_PLAT_ASPEED=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=y
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=y
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+CONFIG_ASPEEDMAC=y
+# CONFIG_MAC0_PHY_LINK is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+CONFIG_SERIAL_AST_DMA_UART=y
+CONFIG_AST_NR_DMA_UARTS=8
+CONFIG_AST_RUNTIME_DMA_UARTS=8
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_AST is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_AST_MISC is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_NVRAM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_AST=y
+CONFIG_I2C_AST1070=y
+CONFIG_AST_I2C_SLAVE_MODE=y
+CONFIG_AST_I2C_SLAVE_EEPROM=y
+# CONFIG_AST_I2C_SLAVE_RDWR is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS 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_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# 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=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+# 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_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# 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=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/ast2300_defconfig b/arch/arm/configs/ast2300_defconfig
new file mode 100644
index 0000000..5ac2120
--- /dev/null
+++ b/arch/arm/configs/ast2300_defconfig
@@ -0,0 +1,1464 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28.9
+# Wed Aug  7 16:52:42 2013
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_ARCH_ASPEED=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+CONFIG_IRMP=y
+# CONFIG_PCEXT is not set
+# CONFIG_REMOTEFX is not set
+# CONFIG_ARCH_AST1100 is not set
+# CONFIG_ARCH_AST2100 is not set
+# CONFIG_ARCH_AST2200 is not set
+CONFIG_ARCH_AST2300=y
+# CONFIG_ARCH_AST2400 is not set
+# CONFIG_ARCH_AST2500 is not set
+
+#
+# FLASH Chip Select
+#
+CONFIG_AST_CS0_NOR=y
+# CONFIG_AST_CS0_NAND is not set
+# CONFIG_AST_CS0_SPI is not set
+# CONFIG_AST_CS0_NONE is not set
+CONFIG_AST_CS1_NOR=y
+# CONFIG_AST_CS1_NAND is not set
+# CONFIG_AST_CS1_SPI is not set
+# CONFIG_AST_CS1_NONE is not set
+CONFIG_AST_CS2_NOR=y
+# CONFIG_AST_CS2_NAND is not set
+# CONFIG_AST_CS2_SPI is not set
+# CONFIG_AST_CS2_NONE is not set
+CONFIG_AST_CS3_NOR=y
+# CONFIG_AST_CS3_NAND is not set
+# CONFIG_AST_CS3_SPI is not set
+# CONFIG_AST_CS3_NONE is not set
+CONFIG_AST_CS4_NOR=y
+# CONFIG_AST_CS4_NAND is not set
+# CONFIG_AST_CS4_SPI is not set
+# CONFIG_AST_CS4_NONE is not set
+# CONFIG_ARCH_AST1070 is not set
+# CONFIG_AST_SCU_LOCK is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+CONFIG_PLAT_ASPEED=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=y
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_FIB_RULES=y
+# CONFIG_WIRELESS is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
+CONFIG_MTD_M25P80=y
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_AST=y
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=y
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+CONFIG_BONDING=y
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+CONFIG_ASPEEDMAC=y
+CONFIG_MAC0_PHY_LINK=y
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_AST_DMA_UART is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_AST is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_AST_MISC is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_NVRAM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_AST is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+CONFIG_AT24=y
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_AST is not set
+CONFIG_SPI_FMC=y
+CONFIG_SPI_BITBANG=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_AST_ADC is not set
+CONFIG_SENSORS_AST_PWM_FAN=y
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_AST_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_BRIGHT=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DELL=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# AST USB Drivers
+#
+CONFIG_AST_USB_UHCI_HCD=y
+# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
+# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
+CONFIG_AST_USB_UHCI_MULTIPORT_4=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AST is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+CONFIG_RTC_DRV_ASPEED=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS 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_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_YAFFS_FS=y
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_9BYTE_TAGS is not set
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# 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=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+# 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_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# 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=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/ast2300_fb_defconfig b/arch/arm/configs/ast2300_fb_defconfig
new file mode 100644
index 0000000..817e089
--- /dev/null
+++ b/arch/arm/configs/ast2300_fb_defconfig
@@ -0,0 +1,1514 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28.9
+# Thu Jan 10 10:44:05 2013
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_ARCH_ASPEED=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+CONFIG_IRMP=y
+# CONFIG_PCEXT is not set
+# CONFIG_REMOTEFX is not set
+# CONFIG_ARCH_AST1100 is not set
+# CONFIG_ARCH_AST2100 is not set
+# CONFIG_ARCH_AST2200 is not set
+CONFIG_ARCH_AST2300=y
+# CONFIG_ARCH_AST2400 is not set
+
+#
+# FLASH Chip Select
+#
+# CONFIG_ASPEED_CS0_NOR is not set
+# CONFIG_ASPEED_CS0_NAND is not set
+CONFIG_ASPEED_CS0_SPI=y
+# CONFIG_ASPEED_CS0_NONE is not set
+# CONFIG_ASPEED_CS1_NOR is not set
+# CONFIG_ASPEED_CS1_NAND is not set
+# CONFIG_ASPEED_CS1_SPI is not set
+CONFIG_ASPEED_CS1_NONE=y
+# CONFIG_ASPEED_CS2_NOR is not set
+# CONFIG_ASPEED_CS2_NAND is not set
+# CONFIG_ASPEED_CS2_SPI is not set
+CONFIG_ASPEED_CS2_NONE=y
+# CONFIG_ASPEED_CS3_NOR is not set
+# CONFIG_ASPEED_CS3_NAND is not set
+# CONFIG_ASPEED_CS3_SPI is not set
+CONFIG_ASPEED_CS3_NONE=y
+# CONFIG_ASPEED_CS4_NOR is not set
+CONFIG_ASPEED_CS4_NAND=y
+# CONFIG_ASPEED_CS4_SPI is not set
+# CONFIG_ASPEED_CS4_NONE is not set
+# CONFIG_ARCH_AST1070 is not set
+# CONFIG_ASPEED_SCU_LOCK is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+CONFIG_PLAT_ASPEED=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=y
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_FIB_RULES=y
+# CONFIG_WIRELESS is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
+CONFIG_MTD_M25P80=y
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_AST=y
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=y
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+CONFIG_BONDING=y
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+CONFIG_ASPEEDMAC=y
+CONFIG_MAC0_PHY_LINK=y
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+CONFIG_SERIAL_ASPEED=y
+CONFIG_SERIAL_ASPEED_CONSOLE=y
+CONFIG_SERIAL_ASPEED_CONSOLE_BAUD=115200
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_NVRAM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_ASPEED=y
+CONFIG_AST_I2C_SLAVE_MODE=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+CONFIG_AT24=y
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_AST=y
+# CONFIG_SPI_FMC is not set
+CONFIG_SPI_BITBANG=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_AST_ADC is not set
+CONFIG_SENSORS_AST_PWM_FAN=y
+# CONFIG_SENSORS_AST_PECI is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_ASPEED_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_ARMCLCD is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_AST=y
+CONFIG_AST_DAC=y
+# CONFIG_AST_DVO is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+# CONFIG_BACKLIGHT_CORGI is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_BRIGHT=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DELL=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# AST USB Drivers
+#
+CONFIG_AST_USB_UHCI_HCD=y
+# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
+# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
+CONFIG_AST_USB_UHCI_MULTIPORT_4=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_ASPEED=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+CONFIG_RTC_DRV_ASPEED=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS 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_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_YAFFS_FS=y
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_9BYTE_TAGS is not set
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# 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=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+# 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_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# 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=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/ast2400_ast1070-1_defconfig b/arch/arm/configs/ast2400_ast1070-1_defconfig
new file mode 100644
index 0000000..93f3df9
--- /dev/null
+++ b/arch/arm/configs/ast2400_ast1070-1_defconfig
@@ -0,0 +1,1038 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28.9
+# Fri Nov  8 16:04:52 2013
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_ARCH_ASPEED=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+CONFIG_IRMP=y
+# CONFIG_PCEXT is not set
+# CONFIG_REMOTEFX is not set
+# CONFIG_ARCH_AST1100 is not set
+# CONFIG_ARCH_AST2100 is not set
+# CONFIG_ARCH_AST2200 is not set
+# CONFIG_ARCH_AST2300 is not set
+CONFIG_ARCH_AST2400=y
+# CONFIG_ARCH_AST2500 is not set
+
+#
+# FLASH Chip Select
+#
+CONFIG_AST_CS0_NOR=y
+# CONFIG_AST_CS0_NAND is not set
+# CONFIG_AST_CS0_SPI is not set
+# CONFIG_AST_CS0_NONE is not set
+CONFIG_AST_CS1_NOR=y
+# CONFIG_AST_CS1_NAND is not set
+# CONFIG_AST_CS1_SPI is not set
+# CONFIG_AST_CS1_NONE is not set
+CONFIG_AST_CS2_NOR=y
+# CONFIG_AST_CS2_NAND is not set
+# CONFIG_AST_CS2_SPI is not set
+# CONFIG_AST_CS2_NONE is not set
+CONFIG_AST_CS3_NOR=y
+# CONFIG_AST_CS3_NAND is not set
+# CONFIG_AST_CS3_SPI is not set
+# CONFIG_AST_CS3_NONE is not set
+CONFIG_AST_CS4_NOR=y
+# CONFIG_AST_CS4_NAND is not set
+# CONFIG_AST_CS4_SPI is not set
+# CONFIG_AST_CS4_NONE is not set
+CONFIG_ARCH_AST1070=y
+CONFIG_AST1070_NR=1
+CONFIG_AST_LPC_PLUS=y
+# CONFIG_AST_LPC is not set
+# CONFIG_AST_SCU_LOCK is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+CONFIG_PLAT_ASPEED=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=y
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=y
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+CONFIG_ASPEEDMAC=y
+# CONFIG_MAC0_PHY_LINK is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+CONFIG_SERIAL_AST_DMA_UART=y
+CONFIG_AST_NR_DMA_UARTS=4
+CONFIG_AST_RUNTIME_DMA_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_AST is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_AST_MISC is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_NVRAM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_AST=y
+CONFIG_I2C_AST1070=y
+CONFIG_AST_I2C_SLAVE_MODE=y
+CONFIG_AST_I2C_SLAVE_EEPROM=y
+# CONFIG_AST_I2C_SLAVE_RDWR is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS 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_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# 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=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+# 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_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# 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=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/ast2400_ast1070_defconfig b/arch/arm/configs/ast2400_ast1070_defconfig
new file mode 100644
index 0000000..552523e
--- /dev/null
+++ b/arch/arm/configs/ast2400_ast1070_defconfig
@@ -0,0 +1,1036 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28.9
+# Mon Jul 15 18:21:08 2013
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_ARCH_ASPEED=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+CONFIG_IRMP=y
+# CONFIG_PCEXT is not set
+# CONFIG_REMOTEFX is not set
+# CONFIG_ARCH_AST1100 is not set
+# CONFIG_ARCH_AST2100 is not set
+# CONFIG_ARCH_AST2200 is not set
+# CONFIG_ARCH_AST2300 is not set
+CONFIG_ARCH_AST2400=y
+# CONFIG_ARCH_AST2500 is not set
+
+#
+# FLASH Chip Select
+#
+CONFIG_AST_CS0_NOR=y
+# CONFIG_AST_CS0_NAND is not set
+# CONFIG_AST_CS0_SPI is not set
+# CONFIG_AST_CS0_NONE is not set
+CONFIG_AST_CS1_NOR=y
+# CONFIG_AST_CS1_NAND is not set
+# CONFIG_AST_CS1_SPI is not set
+# CONFIG_AST_CS1_NONE is not set
+CONFIG_AST_CS2_NOR=y
+# CONFIG_AST_CS2_NAND is not set
+# CONFIG_AST_CS2_SPI is not set
+# CONFIG_AST_CS2_NONE is not set
+CONFIG_AST_CS3_NOR=y
+# CONFIG_AST_CS3_NAND is not set
+# CONFIG_AST_CS3_SPI is not set
+# CONFIG_AST_CS3_NONE is not set
+CONFIG_AST_CS4_NOR=y
+# CONFIG_AST_CS4_NAND is not set
+# CONFIG_AST_CS4_SPI is not set
+# CONFIG_AST_CS4_NONE is not set
+CONFIG_ARCH_AST1070=y
+CONFIG_AST1070_NR=2
+CONFIG_AST_LPC_PLUS=y
+# CONFIG_AST_LPC is not set
+# CONFIG_AST_SCU_LOCK is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+CONFIG_PLAT_ASPEED=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=y
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=y
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+CONFIG_ASPEEDMAC=y
+# CONFIG_MAC0_PHY_LINK is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+CONFIG_SERIAL_AST_DMA_UART=y
+CONFIG_AST_NR_DMA_UARTS=8
+CONFIG_AST_RUNTIME_DMA_UARTS=8
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_AST is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_AST_MISC is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_NVRAM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_AST=y
+CONFIG_I2C_AST1070=y
+CONFIG_AST_I2C_SLAVE_MODE=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS 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_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# 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=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+# 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_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# 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=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/ast2400_defconfig b/arch/arm/configs/ast2400_defconfig
new file mode 100644
index 0000000..22b76fe
--- /dev/null
+++ b/arch/arm/configs/ast2400_defconfig
@@ -0,0 +1,1412 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28.9
+# Tue Jan 20 09:41:35 2015
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_ARCH_ASPEED=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+CONFIG_IRMP=y
+# CONFIG_PCEXT is not set
+# CONFIG_REMOTEFX is not set
+# CONFIG_ARCH_AST1100 is not set
+# CONFIG_ARCH_AST2100 is not set
+# CONFIG_ARCH_AST2200 is not set
+# CONFIG_ARCH_AST2300 is not set
+CONFIG_ARCH_AST2400=y
+# CONFIG_ARCH_AST2500 is not set
+
+#
+# FLASH Chip Select
+#
+# CONFIG_AST_CS0_NOR is not set
+# CONFIG_AST_CS0_NAND is not set
+# CONFIG_AST_CS0_SPI is not set
+CONFIG_AST_CS0_NONE=y
+# CONFIG_AST_CS1_NOR is not set
+# CONFIG_AST_CS1_NAND is not set
+# CONFIG_AST_CS1_SPI is not set
+CONFIG_AST_CS1_NONE=y
+# CONFIG_AST_CS2_NOR is not set
+# CONFIG_AST_CS2_NAND is not set
+# CONFIG_AST_CS2_SPI is not set
+CONFIG_AST_CS2_NONE=y
+# CONFIG_AST_CS3_NOR is not set
+# CONFIG_AST_CS3_NAND is not set
+# CONFIG_AST_CS3_SPI is not set
+CONFIG_AST_CS3_NONE=y
+# CONFIG_AST_CS4_NOR is not set
+# CONFIG_AST_CS4_NAND is not set
+# CONFIG_AST_CS4_SPI is not set
+CONFIG_AST_CS4_NONE=y
+# CONFIG_ARCH_AST1070 is not set
+# CONFIG_AST_SCU_LOCK is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+CONFIG_PLAT_ASPEED=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=y
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=y
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+CONFIG_BONDING=y
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+CONFIG_ASPEEDMAC=y
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_AST_DMA_UART is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_AST is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_AST_MISC=y
+# CONFIG_AST_VIDEO is not set
+# CONFIG_ADC_CAT9883 is not set
+# CONFIG_AST_SPI_BIOS is not set
+CONFIG_AST_PECI=y
+# CONFIG_AST_KCS is not set
+# CONFIG_AST_GPIO is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_NVRAM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_AST=y
+CONFIG_AST_I2C_SLAVE_MODE=y
+CONFIG_AST_I2C_SLAVE_EEPROM=y
+# CONFIG_AST_I2C_SLAVE_RDWR is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+CONFIG_AT24=y
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_SENSORS_AST_ADC=y
+CONFIG_SENSORS_AST_PWM_FAN=y
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AST_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_BRIGHT=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DELL=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_AST=y
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# AST USB Drivers
+#
+CONFIG_AST_USB_UHCI_HCD=y
+# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
+# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
+CONFIG_AST_USB_UHCI_MULTIPORT_4=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_AST=y
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+CONFIG_RTC_DRV_ASPEED=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS 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_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_YAFFS_FS=y
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_9BYTE_TAGS is not set
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# 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=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+# 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_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# 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=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/ast2400_fb_defconfig b/arch/arm/configs/ast2400_fb_defconfig
new file mode 100644
index 0000000..71a1239
--- /dev/null
+++ b/arch/arm/configs/ast2400_fb_defconfig
@@ -0,0 +1,1516 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28.9
+# Thu Jan 10 10:40:53 2013
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_ARCH_ASPEED=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+CONFIG_IRMP=y
+# CONFIG_PCEXT is not set
+# CONFIG_REMOTEFX is not set
+# CONFIG_ARCH_AST1100 is not set
+# CONFIG_ARCH_AST2100 is not set
+# CONFIG_ARCH_AST2200 is not set
+# CONFIG_ARCH_AST2300 is not set
+CONFIG_ARCH_AST2400=y
+
+#
+# FLASH Chip Select
+#
+# CONFIG_ASPEED_CS0_NOR is not set
+# CONFIG_ASPEED_CS0_NAND is not set
+CONFIG_ASPEED_CS0_SPI=y
+# CONFIG_ASPEED_CS0_NONE is not set
+# CONFIG_ASPEED_CS1_NOR is not set
+# CONFIG_ASPEED_CS1_NAND is not set
+# CONFIG_ASPEED_CS1_SPI is not set
+CONFIG_ASPEED_CS1_NONE=y
+# CONFIG_ASPEED_CS2_NOR is not set
+# CONFIG_ASPEED_CS2_NAND is not set
+# CONFIG_ASPEED_CS2_SPI is not set
+CONFIG_ASPEED_CS2_NONE=y
+# CONFIG_ASPEED_CS3_NOR is not set
+# CONFIG_ASPEED_CS3_NAND is not set
+# CONFIG_ASPEED_CS3_SPI is not set
+CONFIG_ASPEED_CS3_NONE=y
+# CONFIG_ASPEED_CS4_NOR is not set
+CONFIG_ASPEED_CS4_NAND=y
+# CONFIG_ASPEED_CS4_SPI is not set
+# CONFIG_ASPEED_CS4_NONE is not set
+# CONFIG_ARCH_AST1070 is not set
+# CONFIG_ASPEED_SCU_LOCK is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+CONFIG_PLAT_ASPEED=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=y
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_FIB_RULES=y
+# CONFIG_WIRELESS is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
+CONFIG_MTD_M25P80=y
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_AST=y
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=y
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+CONFIG_BONDING=y
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+CONFIG_ASPEEDMAC=y
+CONFIG_MAC0_PHY_LINK=y
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_ASPEED is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_NVRAM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_ASPEED=y
+CONFIG_AST_I2C_SLAVE_MODE=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+CONFIG_AT24=y
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_AST is not set
+CONFIG_SPI_FMC=y
+CONFIG_SPI_BITBANG=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_AST_ADC is not set
+CONFIG_SENSORS_AST_PWM_FAN=y
+# CONFIG_SENSORS_AST_PECI is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_ASPEED_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_ARMCLCD is not set
+CONFIG_FB_UVESA=y
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_AST=y
+CONFIG_AST_DAC=y
+# CONFIG_AST_DVO is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_BRIGHT=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DELL=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_AST=y
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# AST USB Drivers
+#
+CONFIG_AST_USB_UHCI_HCD=y
+# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
+# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
+CONFIG_AST_USB_UHCI_MULTIPORT_4=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_ASPEED=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+CONFIG_RTC_DRV_ASPEED=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS 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_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_YAFFS_FS=y
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_9BYTE_TAGS is not set
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# 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=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+# 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_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# 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=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/ast2400_slt_defconfig b/arch/arm/configs/ast2400_slt_defconfig
new file mode 100644
index 0000000..fece826
--- /dev/null
+++ b/arch/arm/configs/ast2400_slt_defconfig
@@ -0,0 +1,1015 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28.9
+# Thu Mar 27 14:10:01 2014
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_ARCH_ASPEED=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+CONFIG_IRMP=y
+# CONFIG_PCEXT is not set
+# CONFIG_REMOTEFX is not set
+# CONFIG_ARCH_AST1100 is not set
+# CONFIG_ARCH_AST2100 is not set
+# CONFIG_ARCH_AST2200 is not set
+# CONFIG_ARCH_AST2300 is not set
+CONFIG_ARCH_AST2400=y
+# CONFIG_ARCH_AST2500 is not set
+
+#
+# FLASH Chip Select
+#
+# CONFIG_AST_CS0_NOR is not set
+# CONFIG_AST_CS0_NAND is not set
+CONFIG_AST_CS0_SPI=y
+# CONFIG_AST_CS0_NONE is not set
+# CONFIG_AST_CS1_NOR is not set
+# CONFIG_AST_CS1_NAND is not set
+# CONFIG_AST_CS1_SPI is not set
+CONFIG_AST_CS1_NONE=y
+# CONFIG_AST_CS2_NOR is not set
+# CONFIG_AST_CS2_NAND is not set
+# CONFIG_AST_CS2_SPI is not set
+CONFIG_AST_CS2_NONE=y
+# CONFIG_AST_CS3_NOR is not set
+# CONFIG_AST_CS3_NAND is not set
+# CONFIG_AST_CS3_SPI is not set
+CONFIG_AST_CS3_NONE=y
+# CONFIG_AST_CS4_NOR is not set
+# CONFIG_AST_CS4_NAND is not set
+# CONFIG_AST_CS4_SPI is not set
+CONFIG_AST_CS4_NONE=y
+# CONFIG_ARCH_AST1070 is not set
+# CONFIG_AST_SCU_LOCK is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+CONFIG_PLAT_ASPEED=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
+CONFIG_MTD_M25P80=y
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_AST=y
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=y
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_AST_DMA_UART is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_AST is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_AST_MISC=y
+# CONFIG_AST_VIDEO is not set
+# CONFIG_ADC_CAT9883 is not set
+# CONFIG_AST_SPI_BIOS is not set
+CONFIG_AST_PECI=y
+# CONFIG_AST_KCS is not set
+# CONFIG_AST_GPIO is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_NVRAM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_AST_I2C_SLAVE_EEPROM is not set
+# CONFIG_AST_I2C_SLAVE_RDWR is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_AST is not set
+CONFIG_SPI_FMC=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AST_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_AST=y
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# AST USB Drivers
+#
+CONFIG_AST_USB_UHCI_HCD=y
+# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
+# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
+CONFIG_AST_USB_UHCI_MULTIPORT_4=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_AST=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS 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_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_YAFFS_FS=y
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_9BYTE_TAGS is not set
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# 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=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+# 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_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# 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=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 21e17dc..8ff0e23 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -21,6 +21,7 @@
 #include <asm/memory.h>
 #include <asm/thread_info.h>
 #include <asm/system.h>
+#include <asm/mach-types.h>
 
 #if (PHYS_OFFSET & 0x001fffff)
 #error "PHYS_OFFSET must be at an even 2MiB boundary!"
@@ -76,13 +77,14 @@
  */
 	.section ".text.head", "ax"
 ENTRY(stext)
+	ldr	r5, =machine_arch_type		@ find the machine type
 	msr	cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
 						@ and irqs disabled
 	mrc	p15, 0, r9, c0, c0		@ get processor id
 	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
 	movs	r10, r5				@ invalid processor (r5=0)?
 	beq	__error_p			@ yes, error 'p'
-	bl	__lookup_machine_type		@ r5=machinfo
+@	bl	__lookup_machine_type		@ r5=machinfo
 	movs	r8, r5				@ invalid machine (r5=0)?
 	beq	__error_a			@ yes, error 'a'
 	bl	__vet_atags
diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
new file mode 100644
index 0000000..a948ab8
--- /dev/null
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -0,0 +1,214 @@
+if ARCH_ASPEED
+
+choice
+        prompt "ASPEED Processor Family"
+        default CONFIG_IRMP
+
+config IRMP
+        bool "IRMP Serials"
+
+config PCEXT
+	bool "PC Extender Serials"
+
+config REMOTEFX
+	bool "RemoteFX Zero-Client Serials"
+
+endchoice
+
+if IRMP
+
+choice
+        prompt "IRMP Serials"
+        default CONFIG_ARCH_AST2300
+
+config ARCH_AST1100
+        bool "AST1100"
+
+config ARCH_AST2100
+        bool "AST2100"
+
+config ARCH_AST2200
+        bool "AST2200"
+
+config ARCH_AST2300
+        bool "AST2300"
+
+config ARCH_AST2400
+	select USB_ARCH_HAS_EHCI
+        bool "AST2400"
+
+config ARCH_AST2500
+	select USB_ARCH_HAS_EHCI
+        bool "AST2500"
+
+endchoice
+
+endif
+
+if PCEXT
+
+choice
+        prompt "PC Extender Serials"
+        default CONFIG_ARCH_AST1510
+
+config ARCH_AST1500
+        bool "AST1500"
+
+config ARCH_AST1510
+        bool "AST1510"
+
+config ARCH_AST1520
+	select USB_ARCH_HAS_EHCI
+	bool "AST1520"
+
+endchoice
+
+endif
+
+if REMOTEFX
+
+choice
+        prompt "RemoteFX Zero-Client Serials"
+        default CONFIG_ARCH_AST3100
+
+config ARCH_AST3100
+	select USB_ARCH_HAS_EHCI
+        bool "AST3100"
+
+config ARCH_AST3200
+	select USB_ARCH_HAS_EHCI
+        bool "AST3200"
+
+endchoice
+
+endif
+
+menu "FLASH Chip Select"
+
+choice
+        prompt "CS0 Config"
+        default CONFIG_AST_CS0_SPI
+
+config AST_CS0_NOR
+        bool "NOR"
+
+config AST_CS0_NAND
+        bool "NAND"
+
+config AST_CS0_SPI
+        bool "SPI_NOR"
+
+config AST_CS0_NONE
+	bool "NONE"
+
+endchoice
+
+choice
+        prompt "CS1 Config"
+        default CONFIG_AST_CS1_SPI
+
+config AST_CS1_NOR
+        bool "NOR"
+
+config AST_CS1_NAND
+        bool "NAND"
+
+config AST_CS1_SPI
+        bool "SPI_NOR"
+
+config AST_CS1_NONE
+        bool "NONE"
+
+endchoice
+
+choice
+        prompt "CS2 Config"
+        default CONFIG_AST_CS2_SPI
+
+config AST_CS2_NOR
+        bool "NOR"
+
+config AST_CS2_NAND
+        bool "NAND"
+
+config AST_CS2_SPI
+        bool "SPI_NOR"
+
+config AST_CS2_NONE
+        bool "NONE"
+
+endchoice
+
+choice
+        prompt "CS3 Config"
+        default CONFIG_AST_CS3_SPI
+
+config AST_CS3_NOR
+        bool "NOR"
+
+config AST_CS3_NAND
+        bool "NAND"
+
+config AST_CS3_SPI
+        bool "SPI_NOR"
+
+config AST_CS3_NONE
+        bool "NONE"
+
+endchoice
+
+choice
+        prompt "CS4 Config"
+        default CONFIG_AST_CS4_SPI
+
+config AST_CS4_NOR
+        bool "NOR"
+
+config AST_CS4_NAND
+        bool "NAND"
+
+config AST_CS4_SPI
+        bool "SPI_NOR"
+
+config AST_CS4_NONE
+        bool "NONE"
+
+endchoice
+
+endmenu
+
+config ARCH_AST1070
+	bool "AST1070 Comapnion chip combination"
+
+config AST1070_NR
+	int "Number of AST1070 Comapniion Chip combination"
+	depends on ARCH_AST1070
+	default "1"
+	help
+	  Set this to the number of ast1070
+
+choice
+        prompt "Connect Bus Interface"
+	depends on ARCH_AST1070
+        default CONFIG_AST_LPC_PLUS
+
+config AST_LPC_PLUS
+        bool "LPC PLUS"
+
+config AST_LPC
+        bool "LPC"
+
+endchoice
+
+config AST_SCU_LOCK
+	bool "AST SCU Protection Key"
+
+# Support PCIE
+config PCIE
+        bool "ASPEED PCIE support"
+        depends on PCI && ARCH_ASPEED
+        select ARCH_SUPPORTS_MSI
+        help
+          Socle PCIE support
+
+endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
new file mode 100644
index 0000000..ae63d8c
--- /dev/null
+++ b/arch/arm/mach-aspeed/Makefile
@@ -0,0 +1,22 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support (must be linked before board specific support)
+
+# Specific board support
+obj-$(CONFIG_ARCH_AST1100) += ast1100.o
+obj-$(CONFIG_ARCH_AST2100) += ast2100.o
+obj-$(CONFIG_ARCH_AST2300) += ast2300.o gpio.o ast-lpc.o
+obj-$(CONFIG_ARCH_AST2400) += ast2400.o gpio.o ast-lpc.o ast-lpc_plus.o
+obj-$(CONFIG_ARCH_AST2500) += ast2500.o ast-mctp.o
+#PC Ext
+obj-$(CONFIG_ARCH_AST1510) += ast1510.o gpio.o
+obj-$(CONFIG_ARCH_AST1520) += ast1520.o ast-mctp.o
+
+#RemoteFx Zero client
+obj-$(CONFIG_ARCH_AST3100) += ast3100.o gpio.o
+obj-$(CONFIG_ARCH_AST3200) += ast3200.o ast-mctp.o
+
+#BMC Comapnion Controller
+obj-$(CONFIG_ARCH_AST1070) += ast1070.o
diff --git a/arch/arm/mach-aspeed/Makefile.boot b/arch/arm/mach-aspeed/Makefile.boot
new file mode 100644
index 0000000..a1e3bf8
--- /dev/null
+++ b/arch/arm/mach-aspeed/Makefile.boot
@@ -0,0 +1,42 @@
+ifeq ($(CONFIG_ARCH_AST1510),y)
+   zreladdr-y   := 0x40008000
+params_phys-y   := 0x40000100
+initrd_phys-y   := 0x40800000
+endif
+
+ifeq ($(CONFIG_ARCH_AST2300),y)
+   zreladdr-y	:= 0x40008000
+params_phys-y	:= 0x40000100
+initrd_phys-y	:= 0x40800000
+endif
+
+ifeq ($(CONFIG_ARCH_AST2400),y)
+   zreladdr-y   := 0x40008000
+params_phys-y   := 0x40000100
+initrd_phys-y   := 0x40800000
+endif
+
+ifeq ($(CONFIG_ARCH_AST2500),y)
+   zreladdr-y   := 0x80008000
+params_phys-y   := 0x80000100
+initrd_phys-y   := 0x80800000
+endif
+
+ifeq ($(CONFIG_ARCH_AST3100),y)
+   zreladdr-y   := 0x40008000
+params_phys-y   := 0x40000100
+initrd_phys-y   := 0x40800000
+endif
+
+ifeq ($(CONFIG_ARCH_AST1520),y)
+   zreladdr-y   := 0x80008000
+params_phys-y   := 0x80000100
+initrd_phys-y   := 0x80800000
+endif
+
+ifeq ($(CONFIG_ARCH_AST3200),y)
+   zreladdr-y   := 0x80008000
+params_phys-y   := 0x80000100
+initrd_phys-y   := 0x80800000
+endif
+
diff --git a/arch/arm/mach-aspeed/ast-lpc.c b/arch/arm/mach-aspeed/ast-lpc.c
new file mode 100644
index 0000000..b26e2cc
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast-lpc.c
@@ -0,0 +1,423 @@
+/********************************************************************************
+* File Name     : arch/arm/mach-aspeed/ast-lpc.c 
+* Author         : Ryan Chen
+* Description   : AST LPC
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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 
+
+*   History      : 
+*    1. 2013/05/15 Ryan Chen Create
+* 
+********************************************************************************/
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#include <mach/platform.h>
+#include <asm/io.h>
+#include <linux/interrupt.h>
+
+#include <mach/hardware.h>
+
+#include <plat/regs-lpc.h>
+#include <plat/ast-snoop.h>
+#include <plat/ast-lpc.h>
+#ifdef CONFIG_ARCH_AST1070
+#include <plat/ast1070-scu.h>
+#include <plat/ast1070-devs.h>
+#include <plat/regs-ast1070-intc.h>
+#include <plat/ast1070-uart-dma.h>
+#endif
+
+//#define AST_LPC_DEBUG
+
+#ifdef AST_LPC_DEBUG
+#define LPCDBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
+#else
+#define LPCDBUG(fmt, args...)
+#endif
+
+#if 0
+static inline u32 
+ast_lpc_read(u32 reg)
+{
+	u32 val;
+		
+	val = readl(ast_lpc_base + reg);
+	
+	LPCDBUG("ast_lpc_read : reg = 0x%08x, val = 0x%08x\n", reg, val);
+	
+	return val;
+}
+
+static inline void
+ast_lpc_write(u32 val, u32 reg) 
+{
+	LPCDBUG("ast_lpc_write : reg = 0x%08x, val = 0x%08x\n", reg, val);
+	writel(val, ast_lpc_base + reg);
+}
+
+/******************************************************************************/
+
+//Suppose you are going to snoop 0x80 ~ 0x87
+//snoop_init(0x80, 0x7, WORD_MODE, buf_dma, (SNOOP_DMA_BOUNDARY / 4)); //register in unit of DWORD
+#if 0
+extern void
+ast_lpc_snoop_dma_enable(u16 port_number, u8 port_mask, u8 mode, dma_addr_t dma_base, u16 size)
+{
+	write_register(0x1e789134, (port_mask << 16) + port_number);
+	write_register(0x1e7890d0, dma_base);
+	write_register(0x1e7890d4, (size - 1));
+	write_register(0x1e789130, (mode << 4) | ENABLE_DMA_INTERRUPT | ENABLE_POST_CODE_FUNCTION | ENABLE_SNOOP_DMA_MODE);
+
+	//Enable error interrupt to check LPC reset
+	write_register_or(0x1e789008, 1);
+
+}
+
+EXPORT_SYMBOL(ast_lpc_snoop_dma_init);
+#endif
+
+extern irqreturn_t ast_snoop_handler(int this_irq, void *dev_id)
+{
+	u32 snoop_sts;
+	struct ast_snoop *snoop = dev_id;
+	
+	snoop_sts = ast_lpc_read(AST_LPC_HICR6);
+	if((snoop_sts & (LPC_HICR6_STR_SNP1W | LPC_HICR6_STR_SNP0W)) == 0)
+		return IRQ_NONE;
+
+	if(snoop_sts & LPC_HICR6_STR_SNP0W) {
+		snoop->snoop_ch0->snoop_data = GET_LPC_SNPD0(ast_lpc_read(AST_LPC_SNPWDR)); 
+		//clear 
+		ast_lpc_write(LPC_HICR6_STR_SNP0W, AST_LPC_HICR6);
+	}
+
+	if(snoop_sts & LPC_HICR6_STR_SNP1W) {
+		snoop->snoop_ch1->snoop_data = GET_LPC_SNPD1(ast_lpc_read(AST_LPC_SNPWDR)); 
+		//clear 
+		ast_lpc_write(LPC_HICR6_STR_SNP1W, AST_LPC_HICR6);
+		
+	}
+
+	return IRQ_HANDLED;
+
+}
+EXPORT_SYMBOL(ast_snoop_handler);
+
+extern irqreturn_t ast_snoop_dma_handler(int this_irq, void *dev_id)
+{
+	u32 snoop_dma_sts, lpc_sts;
+	struct ast_snoop_dma_channel *snoop_dma_ch = dev_id;
+
+	snoop_dma_sts = ast_lpc_read(AST_LPC_PCCR2);
+
+	lpc_sts = ast_lpc_read(AST_LPC_HICR2);
+	
+	printk("ISR : snoop_dma_sts = %x , lpc_sts = %x \n",snoop_dma_sts, lpc_sts);
+
+	if(lpc_sts & LPC_LRST) {
+		printk("LPC RST === > \n");
+		//clear fifo ??		
+		ast_lpc_write(ast_lpc_read(AST_LPC_PCCR0) | LPC_RX_FIFO_CLR, AST_LPC_PCCR0);
+		//clear 
+		ast_lpc_write(lpc_sts & ~LPC_LRST, AST_LPC_HICR2);
+		
+	}
+
+	if(snoop_dma_sts & LPC_POST_CODE_DMA_RDY) {
+		
+		
+	}
+
+
+	return IRQ_HANDLED;
+
+}
+EXPORT_SYMBOL(ast_snoop_dma_handler);
+
+extern void ast_snoop_channel_int_enable(struct ast_snoop_channel	*ast_ch, u8 enable)
+{
+	printk("ch[%d]int : %s , snoop port : %x",ast_ch->snoop_ch, enable? "Enable":"Disable", ast_ch->snoop_port);
+
+	if(enable) {
+		switch(ast_ch->snoop_ch) {
+			case 0:
+				//enable
+				ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) | LPC_HICR5_SNP0INT_EN, 
+							AST_LPC_HICR5);				
+				break;
+			case 1:
+				//enable
+				ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) | LPC_HICR5_SNP1INT_EN, 
+							AST_LPC_HICR5);								
+				break;
+		};
+		
+	} else {
+		switch(ast_ch->snoop_ch) {
+			case 0:
+				//disable
+				ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) & ~LPC_HICR5_SNP0INT_EN, 
+							AST_LPC_HICR5);
+		
+				break;
+			case 1:
+				//disable
+				ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) & ~LPC_HICR5_SNP1INT_EN, 
+							AST_LPC_HICR5);
+		};
+	
+	}
+
+}
+EXPORT_SYMBOL(ast_snoop_channel_int_enable);
+
+extern void ast_snoop_channel_enable(struct ast_snoop_channel *ast_ch, u8 enable)
+{
+	printk("ch[%d] : %s , snoop port : %x",ast_ch->snoop_ch, enable? "Enable":"Disable", ast_ch->snoop_port);
+
+	if(enable) {
+		switch(ast_ch->snoop_ch) {
+			case 0:
+				//disable
+				ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) & ~LPC_HICR5_SNP0W_EN, 
+							AST_LPC_HICR5);
+
+				//set port address 				
+				ast_lpc_write((ast_lpc_read(AST_LPC_SNPWADR) & ~LPC_SNOOP_ADDR0_MASK) | 
+							ast_ch->snoop_port, 
+							AST_LPC_SNPWADR);
+				//enable
+				ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) | LPC_HICR5_SNP0W_EN, 
+							AST_LPC_HICR5);				
+				break;
+			case 1:
+				//disable
+				ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) & ~LPC_HICR5_SNP1W_EN, 
+							AST_LPC_HICR5);
+
+				//set port address				
+				ast_lpc_write((ast_lpc_read(AST_LPC_SNPWADR) & ~LPC_SNOOP_ADDR1_MASK) | 
+							ast_ch->snoop_port, 
+							AST_LPC_SNPWADR);
+				//enable
+				ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) | LPC_HICR5_SNP1W_EN, 
+							AST_LPC_HICR5);								
+				break;
+		};
+		
+	} else {
+		switch(ast_ch->snoop_ch) {
+			case 0:
+				//disable
+				ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) & ~LPC_HICR5_SNP0W_EN, 
+							AST_LPC_HICR5);
+		
+				break;
+			case 1:
+				//disable
+				ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) & ~LPC_HICR5_SNP1W_EN, 
+							AST_LPC_HICR5);
+		
+		};
+	
+	}
+
+}
+EXPORT_SYMBOL(ast_snoop_channel_enable);
+
+extern void ast_snoop_dma_ch_enable(struct ast_snoop_dma_channel *ast_dma_ch, u8 enable)
+{
+	printk("ch[%d] : %s , snoop port : %x",ast_dma_ch->snoop_ch, enable? "Enable":"Disable", ast_dma_ch->snoop_port);
+
+	if(enable) {
+		//disable
+		ast_lpc_write(ast_lpc_read(AST_LPC_PCCR0) & ~LPC_POST_CODE_EN, 
+					AST_LPC_PCCR0);
+
+		//set port address 				
+		ast_lpc_write((ast_lpc_read(AST_LPC_PCCR0) & ~LPC_POST_ADDR_MASK) |
+							LPC_CAPTURE_ADDR_MASK(ast_dma_ch->snoop_mask) | 
+							LPC_CAPTURE_BASE_ADDR(ast_dma_ch->snoop_port),
+							AST_LPC_PCCR0);
+
+		ast_lpc_write(ast_dma_ch->dma_addr,	AST_LPC_PCCR4);
+		ast_lpc_write(ast_dma_ch->dma_size - 1 , AST_LPC_PCCR5);
+
+		//enable
+		ast_lpc_write((ast_lpc_read(AST_LPC_PCCR0) & ~LPC_POST_CODE_MODE_MASK) |
+					LPC_POST_CODE_MODE(ast_dma_ch->snoop_mode) |
+					LPC_POST_DMA_MODE_EN |
+					LPC_POST_CODE_EN, 
+					AST_LPC_PCCR0);				
+	
+	} else {
+		//disable
+		ast_lpc_write(ast_lpc_read(AST_LPC_PCCR0) & ~LPC_POST_CODE_EN, 
+					AST_LPC_PCCR0);
+	}
+
+}
+EXPORT_SYMBOL(ast_snoop_dma_ch_enable);
+
+extern int ast_snoop_init(struct ast_snoop *snoop)
+{
+	int ret=0;
+
+	ast_snoop_channel_enable(snoop->snoop_ch0, 1);
+	ast_snoop_channel_enable(snoop->snoop_ch1, 1);
+	//request irq
+	ret = request_irq(IRQ_LPC, ast_snoop_handler, IRQF_SHARED,
+			  "ast-snoop", snoop);
+	
+	//enable irq
+	ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) | LPC_HICR5_SNP0INT_EN | LPC_HICR5_SNP1INT_EN, 
+				AST_LPC_HICR5); 			
+	return ret;
+}
+EXPORT_SYMBOL(ast_snoop_init);
+
+extern void ast_snoop_dma_init(struct ast_snoop_dma_channel *ast_dma_ch)
+{
+	int ret=0;
+
+	ast_snoop_dma_ch_enable(ast_dma_ch, 1);
+
+	//request irq
+	ret = request_irq(IRQ_LPC, ast_snoop_dma_handler, IRQF_SHARED,
+			  "ast-snoop", ast_dma_ch);
+	
+	//enable irq
+	ast_lpc_write(ast_lpc_read(AST_LPC_PCCR0) |
+				LPC_POST_DMA_INT_EN,
+				AST_LPC_PCCR0); 
+
+	return ret;
+
+}
+EXPORT_SYMBOL(ast_snoop_dma_init);
+#endif
+static struct ast_lpc_driver_data *lpc_driver_data;
+
+static int __devinit ast_lpc_probe(struct platform_device *pdev)
+{
+//	const struct platform_device_id *id = platform_get_device_id(pdev);
+	struct resource *res;
+	int ret = 0;
+	int i;
+
+	lpc_driver_data = kzalloc(sizeof(struct ast_lpc_driver_data), GFP_KERNEL);
+	if (lpc_driver_data == NULL) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	lpc_driver_data->pdev = pdev;
+
+	lpc_driver_data->bus_info = pdev->dev.platform_data;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "no memory resource defined\n");
+		ret = -ENODEV;
+		goto err_free;
+	}
+
+	res = request_mem_region(res->start, resource_size(res), pdev->name);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "failed to request memory resource\n");
+		ret = -EBUSY;
+		goto err_free;
+	}
+
+	lpc_driver_data->reg_base = ioremap(res->start, resource_size(res));
+	if (lpc_driver_data->reg_base == NULL) {
+		dev_err(&pdev->dev, "failed to ioremap() registers\n");
+		ret = -ENODEV;
+		goto err_free_mem;
+	}
+
+#ifdef CONFIG_ARCH_AST1070
+	if(lpc_driver_data->bus_info->bus_scan) {
+		printk("LPC Scan Device... \n");		
+		for(i=0;i<lpc_driver_data->bus_info->scan_node;i++) {
+			ast1070_scu_init(i ,lpc_driver_data->bus_info->bridge_phy_addr + i*0x10000);
+			printk("C%d-[%x] ", i, ast1070_revision_id_info(i));
+			ast1070_vic_init(i, (lpc_driver_data->bus_info->bridge_phy_addr + i*0x10000), IRQ_C0_VIC_CHAIN + i, IRQ_C0_VIC_CHAIN_START + (i*AST_CVIC_NUM));
+			ast1070_scu_dma_init(i);
+			ast1070_uart_dma_init(i, lpc_driver_data->bus_info->bridge_phy_addr);
+			ast_add_device_cuart(i,lpc_driver_data->bus_info->bridge_phy_addr + i*0x10000);
+			ast_add_device_ci2c(i,lpc_driver_data->bus_info->bridge_phy_addr + i*0x10000);
+		}
+		printk("\n");
+
+	}
+	
+#endif
+
+	platform_set_drvdata(pdev, lpc_driver_data);
+	return 0;
+
+err_free_mem:
+	release_mem_region(res->start, resource_size(res));
+err_free:
+	kfree(lpc_driver_data);
+
+	return ret;
+}
+
+static int __devexit ast_lpc_remove(struct platform_device *pdev)
+{
+	struct ast_lpc_driver_data *lpc_driver_data;
+	struct resource *res;
+
+	lpc_driver_data = platform_get_drvdata(pdev);
+	if (lpc_driver_data == NULL)
+		return -ENODEV;
+
+	iounmap(lpc_driver_data->reg_base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, resource_size(res));
+
+	kfree(lpc_driver_data);
+
+	return 0;
+}
+
+static struct platform_driver ast_lpc_driver = {
+	.driver		= {
+		.name	= "ast_lpc",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ast_lpc_probe,
+	.remove		= __devexit_p(ast_lpc_remove),
+//	.id_table	= pwm_id_table,
+};
+
+static int __init ast_lpc_init(void)
+{
+	return platform_driver_register(&ast_lpc_driver);
+}
+arch_initcall(ast_lpc_init);
+
+static void __exit ast_lpc_exit(void)
+{
+	platform_driver_unregister(&ast_lpc_driver);
+}
+module_exit(ast_lpc_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-aspeed/ast-lpc_plus.c b/arch/arm/mach-aspeed/ast-lpc_plus.c
new file mode 100644
index 0000000..187b8b8
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast-lpc_plus.c
@@ -0,0 +1,182 @@
+/********************************************************************************
+* File Name     : arch/arm/mach-aspeed/ast-lpc_plus.c 
+* Author         : Ryan Chen
+* Description   : AST LPC
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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 
+
+*   History      : 
+*    1. 2013/05/15 Ryan Chen Create
+* 
+********************************************************************************/
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#include <mach/platform.h>
+#include <asm/io.h>
+#include <linux/interrupt.h>
+
+#include <mach/hardware.h>
+
+#include <plat/regs-lpc.h>
+#include <plat/ast-snoop.h>
+#include <plat/ast-lpc.h>
+#ifdef CONFIG_ARCH_AST1070
+#include <plat/ast1070-scu.h>
+#include <plat/ast1070-devs.h>
+#include <plat/regs-ast1070-intc.h>
+#include <plat/ast1070-uart-dma.h>
+#endif
+
+//#define AST_LPCP_DEBUG
+
+#ifdef AST_LPCP_DEBUG
+#define LPCP_DBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
+#else
+#define LPCP_DBUG(fmt, args...)
+#endif
+
+#if 0
+static inline u32 
+ast_lpc_plus_write(u32 reg)
+{
+	u32 val;
+		
+	val = readl(ast_lpc_base + reg);
+	
+	LPCDBUG("ast_lpc_read : reg = 0x%08x, val = 0x%08x\n", reg, val);
+	
+	return val;
+}
+
+static inline void
+ast_lpc_plus_write(u32 val, u32 reg) 
+{
+	LPCDBUG("ast_lpc_write : reg = 0x%08x, val = 0x%08x\n", reg, val);
+	writel(val, ast_lpc_base + reg);
+}
+#endif 
+
+static int __devinit ast_lpc_plus_probe(struct platform_device *pdev)
+{
+	static struct ast_lpc_driver_data *lpc_plus_driver_data;
+//	const struct platform_device_id *id = platform_get_device_id(pdev);
+	struct resource *res;
+	int ret = 0;
+	int i;
+
+	lpc_plus_driver_data = kzalloc(sizeof(struct ast_lpc_driver_data), GFP_KERNEL);
+	if (lpc_plus_driver_data == NULL) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	lpc_plus_driver_data->pdev = pdev;
+
+	lpc_plus_driver_data->bus_info = pdev->dev.platform_data;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "no memory resource defined\n");
+		ret = -ENODEV;
+		goto err_free;
+	}
+
+	res = request_mem_region(res->start, resource_size(res), pdev->name);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "failed to request memory resource\n");
+		ret = -EBUSY;
+		goto err_free;
+	}
+
+	lpc_plus_driver_data->reg_base = ioremap(res->start, resource_size(res));
+	if (lpc_plus_driver_data->reg_base == NULL) {
+		dev_err(&pdev->dev, "failed to ioremap() registers\n");
+		ret = -ENODEV;
+		goto err_free_mem;
+	}
+
+#ifdef CONFIG_ARCH_AST1070
+	if(lpc_plus_driver_data->bus_info->bus_scan) {
+		printk("LPC PLUS Scan Device...  ");
+		for(i=0;i<lpc_plus_driver_data->bus_info->scan_node;i++) {
+			ast1070_scu_init(i ,lpc_plus_driver_data->bus_info->bridge_phy_addr + i*0x10000);
+			printk("C%d-[%x] ", i, ast1070_revision_id_info(i));
+			ast1070_vic_init(i, (lpc_plus_driver_data->bus_info->bridge_phy_addr + i*0x10000), IRQ_C0_VIC_CHAIN + i, IRQ_C0_VIC_CHAIN_START + (i*AST_CVIC_NUM));
+			ast1070_scu_dma_init(i);
+			ast1070_uart_dma_init(i, lpc_plus_driver_data->bus_info->bridge_phy_addr);
+			ast_add_device_cuart(i,lpc_plus_driver_data->bus_info->bridge_phy_addr + i*0x10000);
+			ast_add_device_ci2c(i,lpc_plus_driver_data->bus_info->bridge_phy_addr + i*0x10000);
+		}
+		printk("\n");
+
+	}
+	
+#endif
+
+	platform_set_drvdata(pdev, lpc_plus_driver_data);
+	return 0;
+
+err_free_mem:
+	release_mem_region(res->start, resource_size(res));
+err_free:
+	kfree(lpc_plus_driver_data);
+
+	return ret;
+}
+
+static int __devexit ast_lpc_plus_remove(struct platform_device *pdev)
+{
+	struct ast_lpc_driver_data *lpc_plus_driver_data;
+	struct resource *res;
+
+	lpc_plus_driver_data = platform_get_drvdata(pdev);
+	if (lpc_plus_driver_data == NULL)
+		return -ENODEV;
+
+	iounmap(lpc_plus_driver_data->reg_base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, resource_size(res));
+
+	kfree(lpc_plus_driver_data);
+
+	return 0;
+}
+
+static struct platform_driver ast_lpc_plus_driver = {
+	.driver		= {
+		.name	= "ast_lpc_plus",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ast_lpc_plus_probe,
+	.remove		= __devexit_p(ast_lpc_plus_remove),
+//	.id_table	= pwm_id_table,
+};
+
+static int __init ast_lpc_plus_init(void)
+{
+	return platform_driver_register(&ast_lpc_plus_driver);
+}
+arch_initcall(ast_lpc_plus_init);
+
+static void __exit ast_lpc_plus_exit(void)
+{
+	platform_driver_unregister(&ast_lpc_plus_driver);
+}
+module_exit(ast_lpc_plus_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-aspeed/ast-mctp.c b/arch/arm/mach-aspeed/ast-mctp.c
new file mode 100644
index 0000000..1dd746b
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast-mctp.c
@@ -0,0 +1,153 @@
+/********************************************************************************
+* File Name     : arch/arm/mach-aspeed/ast-mctp.c 
+* Author         : Ryan Chen
+* Description   : AST MCTP Ctrl
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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 
+
+
+*   History      : 
+*    1. 2013/07/15 Ryan Chen Create
+* 
+********************************************************************************/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+	
+#include <mach/platform.h>
+#include <asm/io.h>
+	
+#include <mach/hardware.h>
+#include <plat/regs-mctp.h>
+#include <plat/ast_mctp.h>
+
+//#define AST_MCTP_DEBUG 1
+
+#ifdef AST_MCTP_DEBUG
+#define MCTPDBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
+#else
+#define MCTPDBUG(fmt, args...)
+#endif
+
+static u32 ast_mctp_base = 0;
+static u8 txTag = 0;
+static inline u32 
+ast_mctp_read(u32 reg)
+{
+	u32 val;
+		
+	val = readl(ast_mctp_base + reg);
+	
+	MCTPDBUG("reg = 0x%08x, val = 0x%08x\n", reg, val);
+	
+	return val;
+}
+
+static inline void
+ast_mctp_write(u32 val, u32 reg) 
+{
+	MCTPDBUG("reg = 0x%08x, val = 0x%08x\n", reg, val);
+
+	writel(val, ast_mctp_base + reg);
+}
+
+//***********************************Information ***********************************
+
+extern void ast_pcie_cfg_read(u8 type, u32 bdf_offset, u32 *value)
+{
+	u32 timeout =0;
+	u32 desc3,desc2;
+	txTag %= 0xf;
+//	printf("type = %d, busfunc = %x \n",type, bdf);
+	if((ast_mctp_read(AST_MCTP_INT) & MCTP_RX_COMPLETE) != 0)
+		printk("EEEEEEEE  \n");
+	
+	ast_mctp_write(0x4000001 | (type << 24), AST_MCTP_TX_DESC3);	
+	ast_mctp_write(0x200f | (txTag << 8), AST_MCTP_TX_DESC2);
+	ast_mctp_write(bdf_offset, AST_MCTP_TX_DESC1);
+	ast_mctp_write(0, AST_MCTP_TX_DESC0);
+//	ast_mctp_write(0, AST_MCTP_TX_DATA);
+
+	//trigger
+	ast_mctp_write(7, AST_MCTP_CTRL);	
+	//wait 
+//	printf("trigger \n");
+	while(!(ast_mctp_read(AST_MCTP_INT) & MCTP_RX_COMPLETE)) {
+		timeout++;
+		if(timeout > 10000) {
+			printk("time out \n");
+			*value = 0xffffffff;
+			goto out;
+		}
+	};
+
+	//read 
+	desc3 = ast_mctp_read(AST_MCTP_RX_DESC3);	
+	desc2 = ast_mctp_read(AST_MCTP_RX_DESC2);
+	ast_mctp_read(AST_MCTP_RX_DESC1);	
+
+	if( ((desc3 >> 24) == 0x4A) && 
+		((desc3 & 0xfff) == 0x1) && 
+		((desc2 & 0xe000) == 0)) {
+		*value = ast_mctp_read(AST_MCTP_RX_DATA);
+
+	} else {
+		*value = 0xffffffff;		
+		
+	}
+
+out:
+	txTag++;
+	ast_mctp_write(0x15, AST_MCTP_CTRL);
+	ast_mctp_write(0x3, AST_MCTP_INT);	
+	//wait 
+	while(ast_mctp_read(AST_MCTP_INT) & MCTP_RX_COMPLETE);
+	
+}
+
+extern void ast_pcie_cfg_write(u8 type, u32 bdf_offset, u32 data)
+{
+	txTag %= 0xf;
+
+	ast_mctp_write(0x44000001 | (type << 24), AST_MCTP_TX_DESC3);	
+	ast_mctp_write(0x200f | (txTag << 8), AST_MCTP_TX_DESC2);
+	ast_mctp_write(bdf_offset, AST_MCTP_TX_DESC1);
+	ast_mctp_write(0, AST_MCTP_TX_DESC0);
+	ast_mctp_write(data, AST_MCTP_TX_DATA);	
+
+	//trigger
+	ast_mctp_write(7, AST_MCTP_CTRL);	
+//	printf("trigger \n");	
+	//wait 
+	while(!(ast_mctp_read(AST_MCTP_INT) & MCTP_RX_COMPLETE));
+
+	//read 
+	ast_mctp_read(AST_MCTP_RX_DESC3);	
+	ast_mctp_read(AST_MCTP_RX_DESC2);
+	ast_mctp_read(AST_MCTP_RX_DESC1);	
+	txTag++;	
+	ast_mctp_write(0x15, AST_MCTP_CTRL);
+	ast_mctp_write(0x3, AST_MCTP_INT);	
+	//wait 
+	while(ast_mctp_read(AST_MCTP_INT) & MCTP_RX_COMPLETE);
+
+}
+
+static int __init ast_mctp_init(void)
+{
+	MCTPDBUG("\n");
+	ast_mctp_base = (u32)ioremap(AST_MCTP_BASE , SZ_256);
+	return 0;
+}
+
+subsys_initcall(ast_mctp_init);
+
diff --git a/arch/arm/mach-aspeed/ast1070.c b/arch/arm/mach-aspeed/ast1070.c
new file mode 100644
index 0000000..12ede8b
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast1070.c
@@ -0,0 +1,60 @@
+/*
+ *  linux/arch/arm/mach-ast1070/ast1070.c
+ *
+ * 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/mach/arch.h>
+#include <asm/mach/map.h>
+#include <plat/devs.h>
+#include <plat/ast1070-scu.h>
+#include <plat/ast1070-uart-dma.h>
+#include <mach/time.h>
+#include <mach/gpio.h>
+
+static int __init ast1070_init(void)
+{
+	int i=0;
+	u8 num = 0;
+	if(gpio_get_value(PIN_GPIOI2))
+		num = 2;	//dual 1070
+	else
+		num = 1;	//single 1070
+
+	if(CONFIG_AST1070_NR != num)
+		printk("Please check Configuration !!! \n");
+	
+#if 0	
+	if(gpio_get_value(PIN_GPIOI1))
+		printk("Use LPC+ Bus Access \n");
+	else
+		printk("Use LPC Bus Access \n");		
+#endif
+
+	for(i=0; i< CONFIG_AST1070_NR;i++) {	
+		ast1070_scu_revision_id(i);
+		ast1070_dma_init(i);
+		ast1070_uart_dma_init(i);
+	}
+
+	return 0;
+}
+
+subsys_initcall(ast1070_init);
+
diff --git a/arch/arm/mach-aspeed/ast1100.c b/arch/arm/mach-aspeed/ast1100.c
new file mode 100644
index 0000000..e2629f1
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast1100.c
@@ -0,0 +1,49 @@
+/*
+ *  linux/arch/arm/mach-ast2000/ast2000.c
+ *
+ * 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 <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <mach/time.h>
+
+extern void aspeed_map_io(void);
+extern void aspeed_init_irq(void);
+extern struct sys_timer aspeed_timer;
+
+static void __init aspeed_init(void)
+{
+	ast_add_all_devices();
+}
+
+MACHINE_START(ASPEED, "AST1100")
+	.phys_io		= ASPEED_IO_START,
+//	.phys_ram		= ASPEED_SDRAM_BASE,
+	.io_pg_offst		= (IO_ADDRESS(IO_START)>>18) & 0xfffc,
+	.map_io			= aspeed_map_io,
+	.timer			= &aspeed_timer,
+	.init_irq		= aspeed_init_irq,
+	.init_machine		= aspeed_init,
+MACHINE_END
diff --git a/arch/arm/mach-aspeed/ast2100.c b/arch/arm/mach-aspeed/ast2100.c
new file mode 100644
index 0000000..06da653
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2100.c
@@ -0,0 +1,49 @@
+/*
+ *  linux/arch/arm/mach-ast2100/ast2100.c
+ *
+ * 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 <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <mach/time.h>
+
+extern void aspeed_map_io(void);
+extern void aspeed_init_irq(void);
+extern struct sys_timer aspeed_timer;
+
+static void __init aspeed_init(void)
+{
+	ast_add_all_devices();
+}
+
+MACHINE_START(ASPEED, "AST1100")
+	.phys_io		= ASPEED_IO_START,
+//	.phys_ram		= ASPEED_SDRAM_BASE,
+	.io_pg_offst		= (IO_ADDRESS(IO_START)>>18) & 0xfffc,
+	.map_io			= aspeed_map_io,
+	.timer			= &aspeed_timer,
+	.init_irq		= aspeed_init_irq,
+	.init_machine		= aspeed_init,
+MACHINE_END
diff --git a/arch/arm/mach-aspeed/ast2300.c b/arch/arm/mach-aspeed/ast2300.c
new file mode 100644
index 0000000..a223d74
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2300.c
@@ -0,0 +1,206 @@
+/*
+ *  linux/arch/arm/mach-ast2300/ast2300.c
+ *
+ * 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/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/sysdev.h>
+#include <asm/mach-types.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/time.h>
+#include <mach/hardware.h>
+#include <plat/devs.h>
+
+#include "core.h"
+
+static struct map_desc ast_io_desc[] __initdata = {
+	{ 	
+		.virtual		= IO_ADDRESS(AST_VIC_BASE), 
+		.pfn			= __phys_to_pfn(AST_VIC_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+    }, {
+		.virtual		= IO_ADDRESS(AST_SCU_BASE), 
+		.pfn			= __phys_to_pfn(AST_SCU_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_SDMC_BASE), 
+		.pfn			= __phys_to_pfn(AST_SDMC_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,		
+	}, {
+		.virtual		= IO_ADDRESS(AST_MAC0_BASE),
+		.pfn			= __phys_to_pfn(AST_MAC0_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_MAC1_BASE),
+		.pfn			= __phys_to_pfn(AST_MAC1_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,		
+	}, { 
+		.virtual		= IO_ADDRESS(AST_CRYPTO_BASE), 
+		.pfn			= __phys_to_pfn(AST_CRYPTO_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_XDMA_BASE), 
+		.pfn			= __phys_to_pfn(AST_XDMA_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_MCTP_BASE), 
+		.pfn			= __phys_to_pfn(AST_MCTP_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_SRAM_BASE), 
+		.pfn			= __phys_to_pfn(AST_SRAM_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_2D_BASE), 
+		.pfn			= __phys_to_pfn(AST_2D_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_GPIO_BASE), 
+		.pfn			= __phys_to_pfn(AST_GPIO_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_TIMER_BASE), 
+		.pfn			= __phys_to_pfn(AST_TIMER_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UART0_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART0_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UART4_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART4_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_WDT_BASE), 
+		.pfn			= __phys_to_pfn(AST_WDT_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_VUART0_BASE), 
+		.pfn			= __phys_to_pfn(AST_VUART0_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_PUART_BASE), 
+		.pfn			= __phys_to_pfn(AST_PUART_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_LPC_BASE), 
+		.pfn			= __phys_to_pfn(AST_LPC_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_PECI_BASE), 
+		.pfn			= __phys_to_pfn(AST_PECI_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+#if defined(CONFIG_ARCH_AST1070)
+		.virtual		= IO_ADDRESS2(AST_C0_VIC_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_VIC_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS2(AST_C0_SCU_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_SCU_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS2(AST_C0_I2C_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_I2C_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,
+	}, {	
+		.virtual		= IO_ADDRESS2(AST_C0_UART0_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_UART0_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,		
+	}, {	
+		.virtual		= IO_ADDRESS2(AST_C0_UART1_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_UART0_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,		
+	}, {	
+		.virtual		= IO_ADDRESS2(AST_C0_UART2_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_UART0_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,		
+	}, {	
+		.virtual		= IO_ADDRESS2(AST_C0_UART3_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_UART0_BASE),
+
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,
+	}, { 
+#endif
+		.virtual		= IO_ADDRESS(AST_UART1_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART1_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UART2_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART2_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UART3_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART3_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	},
+};
+
+void __init ast_map_io(void)
+{
+	iotable_init(ast_io_desc, ARRAY_SIZE(ast_io_desc));
+}
+
+static void __init ast_init(void)
+{
+	ast_add_all_devices();
+}
+
+MACHINE_START(ASPEED, "AST2300")
+	.phys_io		= AST_IO_START,
+//	.phys_ram		= AST_SDRAM_BASE,
+	.io_pg_offst		= (IO_ADDRESS(AST_IO_START)>>18) & 0xfffc,
+	.boot_params	= 0x40000100,		
+	.map_io			= ast_map_io,
+	.timer			= &ast_timer,
+	.init_irq		= ast_init_irq,
+	.init_machine		= ast_init,
+MACHINE_END
diff --git a/arch/arm/mach-aspeed/ast2400.c b/arch/arm/mach-aspeed/ast2400.c
new file mode 100644
index 0000000..3567d3c
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2400.c
@@ -0,0 +1,255 @@
+/*
+ *  linux/arch/arm/mach-ast2300/ast2300.c
+ *
+ * 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/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/sysdev.h>
+#include <asm/mach-types.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/time.h>
+#include <mach/hardware.h>
+#include <plat/devs.h>
+
+#include "core.h"
+
+static struct map_desc ast_io_desc[] __initdata = {
+	{ 	
+		.virtual		= IO_ADDRESS(AST_VIC_BASE), 
+		.pfn			= __phys_to_pfn(AST_VIC_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+    }, {
+		.virtual		= IO_ADDRESS(AST_SCU_BASE), 
+		.pfn			= __phys_to_pfn(AST_SCU_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_SDMC_BASE), 
+		.pfn			= __phys_to_pfn(AST_SDMC_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,		
+	}, {
+		.virtual		= IO_ADDRESS(AST_VIDEO_BASE), 
+		.pfn			= __phys_to_pfn(AST_VIDEO_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,		
+	}, {
+		.virtual		= IO_ADDRESS(AST_MAC0_BASE),
+		.pfn			= __phys_to_pfn(AST_MAC0_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_MAC1_BASE),
+		.pfn			= __phys_to_pfn(AST_MAC1_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,		
+	}, { 
+		.virtual		= IO_ADDRESS(AST_CRYPTO_BASE), 
+		.pfn			= __phys_to_pfn(AST_CRYPTO_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_JTAG_BASE), 
+		.pfn			= __phys_to_pfn(AST_JTAG_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_XDMA_BASE), 
+		.pfn			= __phys_to_pfn(AST_XDMA_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_MCTP_BASE), 
+		.pfn			= __phys_to_pfn(AST_MCTP_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_SRAM_BASE), 
+		.pfn			= __phys_to_pfn(AST_SRAM_BASE),
+		.length 		= SZ_16K*2,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_2D_BASE), 
+		.pfn			= __phys_to_pfn(AST_2D_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_GPIO_BASE), 
+		.pfn			= __phys_to_pfn(AST_GPIO_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_TIMER_BASE), 
+		.pfn			= __phys_to_pfn(AST_TIMER_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UART0_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART0_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UART4_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART4_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_WDT_BASE), 
+		.pfn			= __phys_to_pfn(AST_WDT_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UDC11_BASE	), 
+		.pfn			= __phys_to_pfn(AST_UDC11_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_VUART0_BASE), 
+		.pfn			= __phys_to_pfn(AST_VUART0_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_PUART_BASE), 
+		.pfn			= __phys_to_pfn(AST_PUART_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_LPC_BASE), 
+		.pfn			= __phys_to_pfn(AST_LPC_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_PECI_BASE), 
+		.pfn			= __phys_to_pfn(AST_PECI_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+#if defined(CONFIG_ARCH_AST1070)
+		.virtual		= IO_ADDRESS2(AST_C0_VIC_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_VIC_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS2(AST_C0_SCU_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_SCU_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS2(AST_C0_I2C_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_I2C_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS2(AST_C1_VIC_BASE), 
+		.pfn			= __phys_to_pfn(AST_C1_VIC_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS2(AST_C1_SCU_BASE), 
+		.pfn			= __phys_to_pfn(AST_C1_SCU_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS2(AST_C1_I2C_BASE), 
+		.pfn			= __phys_to_pfn(AST_C1_I2C_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,
+	}, {	
+		.virtual		= IO_ADDRESS2(AST_C0_UART0_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_UART0_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,		
+	}, {	
+		.virtual		= IO_ADDRESS2(AST_C0_UART1_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_UART0_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,		
+	}, {	
+		.virtual		= IO_ADDRESS2(AST_C0_UART2_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_UART0_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,		
+	}, {	
+		.virtual		= IO_ADDRESS2(AST_C0_UART3_BASE), 
+		.pfn			= __phys_to_pfn(AST_C0_UART0_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,		
+	}, {	
+		.virtual		= IO_ADDRESS2(AST_C1_UART0_BASE), 
+		.pfn			= __phys_to_pfn(AST_C1_UART0_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,		
+	}, {	
+		.virtual		= IO_ADDRESS2(AST_C1_UART1_BASE), 
+		.pfn			= __phys_to_pfn(AST_C1_UART0_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,		
+	}, {	
+		.virtual		= IO_ADDRESS2(AST_C1_UART2_BASE), 
+		.pfn			= __phys_to_pfn(AST_C1_UART0_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,		
+	}, {	
+		.virtual		= IO_ADDRESS2(AST_C1_UART3_BASE), 
+		.pfn			= __phys_to_pfn(AST_C1_UART0_BASE),
+		.length 		= SZ_1K,
+		.type			= MT_DEVICE,		
+	}, {		
+#endif
+		.virtual		= IO_ADDRESS(AST_UART1_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART1_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UART2_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART2_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UART3_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART3_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	},
+};
+
+void __init ast_map_io(void)
+{
+	iotable_init(ast_io_desc, ARRAY_SIZE(ast_io_desc));
+}
+
+static void __init ast_init(void)
+{
+	ast_add_all_devices();
+}
+
+MACHINE_START(ASPEED, "AST2400")
+	.phys_io		= AST_IO_START,
+//	.phys_ram		= AST_SDRAM_BASE,
+	.io_pg_offst		= (IO_ADDRESS(AST_IO_START)>>18) & 0xfffc,
+	.boot_params	= 0x40000100,	
+	.map_io			= ast_map_io,
+	.timer			= &ast_timer,
+	.init_irq		= ast_init_irq,
+	.init_machine		= ast_init,
+MACHINE_END
diff --git a/arch/arm/mach-aspeed/ast3100.c b/arch/arm/mach-aspeed/ast3100.c
new file mode 100644
index 0000000..cf220e7
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast3100.c
@@ -0,0 +1,230 @@
+/*
+ *  linux/arch/arm/mach-ast2300/ast2300.c
+ *
+ * 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 <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <mach/time.h>
+
+#include <asm/mach/map.h>
+#include <plat/devs.h>
+
+#include "core.h"
+
+static struct map_desc ast_io_desc[] __initdata = {
+	{ 	
+		.virtual		= IO_ADDRESS(AST_AHB_CTRL_BASE),	
+		.pfn			= __phys_to_pfn(AST_AHB_CTRL_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_NEW_SMC_CONTROLLER_BASE),	
+		.pfn			= __phys_to_pfn(AST_NEW_SMC_CONTROLLER_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_LPC_SPI_CONTROLLER_BASE),	
+		.pfn			= __phys_to_pfn(AST_LPC_SPI_CONTROLLER_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_MIC_BASE),	
+		.pfn			= __phys_to_pfn(AST_MIC_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_MAC1_BASE),	
+		.pfn			= __phys_to_pfn(AST_MAC1_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_MAC2_BASE), 
+		.pfn			= __phys_to_pfn(AST_MAC2_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_VIC_BASE), 
+		.pfn			= __phys_to_pfn(AST_VIC_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_SCU_BASE), 
+		.pfn			= __phys_to_pfn(AST_SCU_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_CRYPTO_BASE), 
+		.pfn			= __phys_to_pfn(AST_CRYPTO_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_JTAG_BASE), 
+		.pfn			= __phys_to_pfn(AST_JTAG_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_I2S_BASE), 
+		.pfn			= __phys_to_pfn(AST_I2S_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_GRAPHIC_BASE), 
+		.pfn			= __phys_to_pfn(AST_GRAPHIC_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_XDMA_BASE), 
+		.pfn			= __phys_to_pfn(AST_XDMA_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_MCTP_BASE), 
+		.pfn			= __phys_to_pfn(AST_MCTP_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_ADC_BASE), 
+		.pfn			= __phys_to_pfn(AST_ADC_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_VIDEO_BASE), 
+		.pfn			= __phys_to_pfn(AST_VIDEO_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_SRAM_BASE), 
+		.pfn			= __phys_to_pfn(AST_SRAM_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_SDHC_BASE), 
+		.pfn			= __phys_to_pfn(AST_SDHC_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_2D_BASE), 
+		.pfn			= __phys_to_pfn(AST_2D_BASE),
+		.length 		= SZ_64K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_GPIO_BASE), 
+		.pfn			= __phys_to_pfn(AST_GPIO_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_RTC_BASE), 
+		.pfn			= __phys_to_pfn(AST_RTC_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_TIMER_BASE), 
+		.pfn			= __phys_to_pfn(AST_TIMER_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UART0_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART0_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UART1_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART1_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_WDT_BASE), 
+		.pfn			= __phys_to_pfn(AST_WDT_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_PWM_BASE), 
+		.pfn			= __phys_to_pfn(AST_PWM_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_VUART0_BASE), 
+		.pfn			= __phys_to_pfn(AST_VUART0_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_PUART_BASE), 
+		.pfn			= __phys_to_pfn(AST_PUART_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_LPC_BASE), 
+		.pfn			= __phys_to_pfn(AST_LPC_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, { 
+		.virtual		= IO_ADDRESS(AST_I2C_BASE), 
+		.pfn			= __phys_to_pfn(AST_I2C_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_PECI_BASE), 
+		.pfn			= __phys_to_pfn(AST_PECI_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UART2_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART2_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UART3_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART2_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	}, {
+		.virtual		= IO_ADDRESS(AST_UART4_BASE), 
+		.pfn			= __phys_to_pfn(AST_UART2_BASE),
+		.length 		= SZ_4K,
+		.type			= MT_DEVICE,
+	},
+};
+
+void __init ast_map_io(void)
+{
+	iotable_init(ast_io_desc, ARRAY_SIZE(ast_io_desc));
+}
+
+static void __init ast_init(void)
+{
+	ast_add_all_devices();
+}
+
+MACHINE_START(ASPEED, "AST2300")
+	.phys_io		= AST_IO_START,
+//	.phys_ram		= AST_SDRAM_BASE,
+	.io_pg_offst		= (IO_ADDRESS(AST_IO_START)>>18) & 0xfffc,
+	.boot_params	= 0x40000100,		
+	.map_io			= ast_map_io,
+	.timer			= &ast_timer,
+	.init_irq		= ast_init_irq,
+	.init_machine		= ast_init,
+MACHINE_END
diff --git a/arch/arm/mach-aspeed/core.h b/arch/arm/mach-aspeed/core.h
new file mode 100644
index 0000000..eb5ac89
--- /dev/null
+++ b/arch/arm/mach-aspeed/core.h
@@ -0,0 +1,25 @@
+/*
+ *  linux/arch/arm/mach-aspeed/core.h
+ *
+* Copyright (C) ASPEED Tech. Corp.
+* 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_ASPEED_CORE_H
+#define __ASM_ARCH_ASPEED_CORE_H
+
+extern struct sys_timer ast_timer;
+
+extern void __init ast_init_irq(void);
+#endif
diff --git a/arch/arm/mach-aspeed/gpio.c b/arch/arm/mach-aspeed/gpio.c
new file mode 100644
index 0000000..3a633e9
--- /dev/null
+++ b/arch/arm/mach-aspeed/gpio.c
@@ -0,0 +1,635 @@
+/*
+ *  linux/arch/arm/plat-aspeed/gpio.c
+ *
+ * Support functions for ASPEED GPIO
+ *
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Written by Ryan Chen <ryan_chen@aspeedtech.com>
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+#include <asm/mach/irq.h>
+
+#include <plat/regs-gpio.h>
+#include <asm-generic/gpio.h>
+
+//#define AST_GPIO_DEBUG
+
+#ifdef AST_GPIO_DEBUG
+//#define GPIODBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
+#define GPIODBUG(fmt, args...) printk(fmt, ## args)
+
+#else
+#define GPIODBUG(fmt, args...)
+#endif
+
+/*************************************************************/
+//GPIO group structure 
+struct ast_gpio_bank {
+    int 	irq;
+	u32  	base;	
+//TODO remove base	
+	u32  	index;	
+	u32		data_offset;
+	u32		dir_offset;
+	u32		int_en_offset;	
+	u32		int_type_offset;		
+	u32		int_sts_offset;	
+	u32		rst_tol_offset;		
+	u32		debounce_offset;	
+	u32		cmd_source_offset;		
+	struct gpio_chip chip;
+	
+//#ifdef CONFIG_PM
+//#define NR_REGS         (7)
+//			u32 regs[NR_REGS];
+//#endif
+};
+
+int ast_gpio_to_irq(unsigned gpio)
+{
+	return (gpio + IRQ_GPIO_CHAIN_START);
+}
+
+EXPORT_SYMBOL(ast_gpio_to_irq);
+
+int ast_irq_to_gpio(unsigned irq)
+{
+	return (irq - IRQ_GPIO_CHAIN_START);
+}
+
+EXPORT_SYMBOL(ast_irq_to_gpio);
+
+static inline u32
+ast_gpio_read(struct ast_gpio_bank *ast_gpio ,u32 offset)
+{
+	GPIODBUG("base = 0x%08x, offset = 0x%08x \n", ast_gpio->base, offset);
+
+	return readl(ast_gpio->base + offset);
+}
+
+static inline void
+ast_gpio_write(struct ast_gpio_bank *ast_gpio , u32 val, u32 offset)
+{
+    GPIODBUG("base = 0x%08x, offset = 0x%08x, val = 0x%08x\n", ast_gpio->base, offset, val);
+    writel(val, ast_gpio->base + offset);
+}
+
+/***************************************************************************************/
+static int
+ast_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct ast_gpio_bank *ast_gpio = container_of(chip, struct ast_gpio_bank, chip);
+	unsigned long flags;
+	u32 v;
+	int ret = -1;
+
+	GPIODBUG("dir_in %s[%d] \n",chip->label, offset);
+
+	local_irq_save(flags);
+
+	v = ast_gpio_read(ast_gpio, ast_gpio->dir_offset);
+	
+	v &= ~(GPIO_OUTPUT_MODE << (offset + (ast_gpio->index * 8)));
+	ast_gpio_write(ast_gpio, v, ast_gpio->dir_offset);
+
+	ret = 0;
+
+	local_irq_restore(flags);
+	return ret;
+
+}
+
+static int
+ast_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int val)
+{
+   	struct ast_gpio_bank *ast_gpio = container_of(chip, struct ast_gpio_bank, chip);
+    unsigned long flags;
+    u32 v;
+    int ret = -1;
+	GPIODBUG("dir_out %s[%d], val %d \n",chip->label, offset, val);
+
+    local_irq_save(flags);
+
+	/* Drive as an output */
+	v = ast_gpio_read(ast_gpio, ast_gpio->dir_offset);
+
+	v |= (GPIO_OUTPUT_MODE << (offset + (ast_gpio->index * 8)));
+
+	ast_gpio_write(ast_gpio, v, ast_gpio->dir_offset);
+
+	local_irq_restore(flags);
+	
+	ret = 0;	
+	return ret;
+}
+
+static int
+ast_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+   	struct ast_gpio_bank *ast_gpio = container_of(chip, struct ast_gpio_bank, chip);
+    unsigned long flags;
+    u32 v;
+
+	GPIODBUG("Get %s[%d] \n",chip->label, offset);
+
+    local_irq_save(flags);
+
+    v = ast_gpio_read(ast_gpio, ast_gpio->data_offset);
+
+    v &= (1 << (offset + (ast_gpio->index * 8)));
+	
+	if(v)
+		v = 1;
+	else
+		v = 0;
+
+    local_irq_restore(flags);
+	
+    return v;
+}
+
+static void
+ast_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+   	struct ast_gpio_bank *ast_gpio = container_of(chip, struct ast_gpio_bank, chip);
+    unsigned long flags;
+    u32 v;
+	GPIODBUG("Set %s[%d] = %d\n",chip->label, offset, val);
+
+	local_irq_save(flags);
+
+    /* Set the value */
+
+    v = ast_gpio_read(ast_gpio, ast_gpio->data_offset);
+
+	if (val)
+		v |= (1 << (offset + (ast_gpio->index * 8)));
+	else
+		v &= ~(1 << (offset + (ast_gpio->index * 8)));
+
+	ast_gpio_write(ast_gpio, v, ast_gpio->data_offset);
+
+	local_irq_restore(flags);
+}
+	
+
+#define AST_GPIO_BANK(name, gpio_base, index_no, data, dir, int_en, int_type, int_sts, rst_tol, debounce, cmd_s)	\
+	{												\
+		.base = gpio_base,							\
+		.index = index_no,								\
+		.data_offset = data,						\
+		.dir_offset = dir, 							\
+		.int_en_offset = int_en,					\
+		.int_type_offset = int_type,				\
+		.int_sts_offset = int_sts, 					\
+		.rst_tol_offset = rst_tol,					\
+		.debounce_offset = debounce,				\
+		.cmd_source_offset = cmd_s,					\
+		.chip = {                            							\
+	        .label                  = name,  							\
+	        .direction_input        = ast_gpio_direction_input,         \
+	        .direction_output       = ast_gpio_direction_output,        \
+	        .get            = ast_gpio_get,  \
+	        .set            = ast_gpio_set,  \
+	        .ngpio          = GPIO_PER_PORT_PIN_NUM, \
+		}, \
+	}
+
+static struct ast_gpio_bank ast_gpio_gp[] = {
+	AST_GPIO_BANK("GPIOA", IO_ADDRESS(AST_GPIO_BASE), 0, 0x000, 0x004, 0x008, 0x00c, 0x018, 0x01c, 0x040, 0x060),
+	AST_GPIO_BANK("GPIOB", IO_ADDRESS(AST_GPIO_BASE), 1, 0x000, 0x004, 0x008, 0x00c, 0x018, 0x01c, 0x040, 0x060),
+	AST_GPIO_BANK("GPIOC", IO_ADDRESS(AST_GPIO_BASE), 2, 0x000, 0x004, 0x008, 0x00c, 0x018, 0x01c, 0x040, 0x060),
+	AST_GPIO_BANK("GPIOD", IO_ADDRESS(AST_GPIO_BASE), 3, 0x000, 0x004, 0x008, 0x00c, 0x018, 0x01c, 0x040, 0x060),
+	AST_GPIO_BANK("GPIOE", IO_ADDRESS(AST_GPIO_BASE), 0, 0x020, 0x024, 0x028, 0x02c, 0x038, 0x03c, 0x048, 0x068),
+	AST_GPIO_BANK("GPIOF", IO_ADDRESS(AST_GPIO_BASE), 1, 0x020, 0x024, 0x028, 0x02c, 0x038, 0x03c, 0x048, 0x068),
+	AST_GPIO_BANK("GPIOG", IO_ADDRESS(AST_GPIO_BASE), 2, 0x020, 0x024, 0x028, 0x02c, 0x038, 0x03c, 0x048, 0x068),
+	AST_GPIO_BANK("GPIOH", IO_ADDRESS(AST_GPIO_BASE), 3, 0x020, 0x024, 0x028, 0x02c, 0x038, 0x03c, 0x048, 0x068),
+	AST_GPIO_BANK("GPIOI", IO_ADDRESS(AST_GPIO_BASE), 0, 0x070, 0x074, 0x098, 0x09c, 0x0a8, 0x0ac, 0x0b0, 0x090),
+	AST_GPIO_BANK("GPIOJ", IO_ADDRESS(AST_GPIO_BASE), 1, 0x070, 0x074, 0x098, 0x09c, 0x0a8, 0x0ac, 0x0b0, 0x090),
+	AST_GPIO_BANK("GPIOK", IO_ADDRESS(AST_GPIO_BASE), 2, 0x070, 0x074, 0x098, 0x09c, 0x0a8, 0x0ac, 0x0b0, 0x090),
+	AST_GPIO_BANK("GPIOL", IO_ADDRESS(AST_GPIO_BASE), 3, 0x070, 0x074, 0x098, 0x09c, 0x0a8, 0x0ac, 0x0b0, 0x090),	
+	AST_GPIO_BANK("GPIOM", IO_ADDRESS(AST_GPIO_BASE), 0, 0x078, 0x07c, 0x0e8, 0x0ec, 0x0f8, 0x0fc, 0x100, 0x0e0),	
+	AST_GPIO_BANK("GPION", IO_ADDRESS(AST_GPIO_BASE), 1, 0x078, 0x07c, 0x0e8, 0x0ec, 0x0f8, 0x0fc, 0x100, 0x0e0),
+	AST_GPIO_BANK("GPIOO", IO_ADDRESS(AST_GPIO_BASE), 2, 0x078, 0x07c, 0x0e8, 0x0ec, 0x0f8, 0x0fc, 0x100, 0x0e0),	
+	AST_GPIO_BANK("GPIOP", IO_ADDRESS(AST_GPIO_BASE), 3, 0x078, 0x07c, 0x0e8, 0x0ec, 0x0f8, 0x0fc, 0x100, 0x0e0),
+	AST_GPIO_BANK("GPIOQ", IO_ADDRESS(AST_GPIO_BASE), 0, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
+	AST_GPIO_BANK("GPIOR", IO_ADDRESS(AST_GPIO_BASE), 1, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),	
+	AST_GPIO_BANK("GPIOS", IO_ADDRESS(AST_GPIO_BASE), 2, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
+#if defined(CONFIG_ARCH_AST2400)		
+	AST_GPIO_BANK("GPIOT", IO_ADDRESS(AST_GPIO_BASE), 4, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),	
+	AST_GPIO_BANK("GPIOU", IO_ADDRESS(AST_GPIO_BASE), 0, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
+	AST_GPIO_BANK("GPIOV", IO_ADDRESS(AST_GPIO_BASE), 1, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
+	AST_GPIO_BANK("GPIOW", IO_ADDRESS(AST_GPIO_BASE), 2, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
+	AST_GPIO_BANK("GPIOX", IO_ADDRESS(AST_GPIO_BASE), 3, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
+	AST_GPIO_BANK("GPIOY", IO_ADDRESS(AST_GPIO_BASE), 0, 0x1e0, 0x1e4, 0x178, 0x17c, 0x188, 0x18c, 0x190, 0x170),
+	AST_GPIO_BANK("GPIOZ", IO_ADDRESS(AST_GPIO_BASE), 1, 0x1e0, 0x1e4, 0x178, 0x17c, 0x188, 0x18c, 0x190, 0x170),
+	AST_GPIO_BANK("GPIOAA", IO_ADDRESS(AST_GPIO_BASE), 2, 0x1e0, 0x1e4, 0x178, 0x17c, 0x188, 0x18c, 0x190, 0x170),
+	AST_GPIO_BANK("GPIOAB", IO_ADDRESS(AST_GPIO_BASE), 3, 0x1e0, 0x1e4, 0x178, 0x17c, 0x188, 0x18c, 0x190, 0x170),	
+#endif	
+};
+
+
+/***************************************************************************************/
+/*
+ * assuming the pin is muxed as a gpio output, set its value.
+ */
+int ast_set_gpio_value(unsigned gpio_pin, int value)
+{
+	u32 data;
+	u32 gp, pin;
+	gp = gpio_pin / 8;
+	pin = gpio_pin % 32;
+	data = ast_gpio_read(&ast_gpio_gp[gp], ast_gpio_gp[gp].data_offset);
+	if(value)
+		data |= (1 << pin);
+	else
+		data &= ~(1 << pin);
+	
+	GPIODBUG("gp : %d, pin %d, data = %x \n ", gp, pin, data);
+	ast_gpio_write(&ast_gpio_gp[gp], data, ast_gpio_gp[gp].data_offset);
+
+	return 0;
+}
+EXPORT_SYMBOL(ast_set_gpio_value);
+
+
+/*
+ * read the pin's value (works even if it's not muxed as a gpio).
+ */
+int ast_get_gpio_value(unsigned gpio_pin)
+{
+	u32 data;
+	u32 gp, pin;
+	gp = gpio_pin / 8;
+	pin = gpio_pin % 32;
+	data = ast_gpio_read(&ast_gpio_gp[gp], ast_gpio_gp[gp].data_offset);
+
+	GPIODBUG("gp : %d, pin %d, data = %x, value = %d \n ", gp, pin, data, (data >> pin) & 1);
+
+	return ((data >> pin) & 1);
+}
+EXPORT_SYMBOL(ast_get_gpio_value);
+
+//timer 0/1/2
+//Debounce time = PCLK * (val+1)
+void ast_set_gpio_debounce_timer(int timer, int val)
+{
+	switch(timer) {
+		case 0:
+			writel(val, IO_ADDRESS(AST_GPIO_BASE) + 0x50);
+			break;
+		case 1:
+			writel(val, IO_ADDRESS(AST_GPIO_BASE) + 0x54);
+			break;
+		case 2:
+			writel(val, IO_ADDRESS(AST_GPIO_BASE) + 0x58);
+			break;
+	}
+}
+
+EXPORT_SYMBOL(ast_set_gpio_debounce_timer);
+
+//TODO ......
+//mode 0 : no debounce , 1: set  0x50, 2: 0x54, 3: 0x58
+void ast_set_gpio_debounce(int gpio_port, int mode)
+{
+#if 0 
+	u32 set0, set1;
+	u16 gp, port;
+	gp = gpio_port / 4;
+	port = gpio_port % 4;
+	set0 = ast_gpio_read(&ast_gpio_gp[gp], ast_gpio_gp[gp].debounce_offset);
+	set1 = ast_gpio_read(&ast_gpio_gp[gp], ast_gpio_gp[gp].debounce_offset + 0x04);
+
+	switch(port) {
+		case 0:		//A , H , ......
+			set0 = port 
+			ast_gpio_write(ast_gpio, val, 0x50);
+			break;
+		case 1:
+			ast_gpio_write(ast_gpio, val, 0x54);
+			break;
+		case 2:
+			ast_gpio_write(ast_gpio, val, 0x58);
+			break;
+		case 3:
+			ast_gpio_write(ast_gpio, val, 0x58);
+		break;
+		default:
+			GPIODBUG("not support \n");
+			return;
+		break;
+
+	}
+
+	ast_gpio_write(&ast_gpio_gp[gp], set0, ast_gpio_gp[gp].debounce_offset);
+	ast_gpio_write(&ast_gpio_gp[gp], set1, ast_gpio_gp[gp].debounce_offset + 0x04);
+#endif
+}
+
+EXPORT_SYMBOL(ast_set_gpio_debounce);
+
+//TODO ......
+//
+void ast_set_gpio_tolerant(int gpio_port, int mode)
+{
+#if 0 
+	u32 set0, set1;
+	u16 gp, port;
+	gp = gpio_port / 4;
+	port = gpio_port % 4;
+	set0 = ast_gpio_read(&ast_gpio_gp[gp], ast_gpio_gp[gp].debounce_offset);
+	set1 = ast_gpio_read(&ast_gpio_gp[gp], ast_gpio_gp[gp].debounce_offset + 0x04);
+
+	switch(port) {
+		case 0:		//A , H , ......
+			set0 = port 
+			ast_gpio_write(ast_gpio, val, 0x50);
+			break;
+		case 1:
+			ast_gpio_write(ast_gpio, val, 0x54);
+			break;
+		case 2:
+			ast_gpio_write(ast_gpio, val, 0x58);
+			break;
+		case 3:
+			ast_gpio_write(ast_gpio, val, 0x58);
+		break;
+		default:
+			GPIODBUG("not support \n");
+			return;
+		break;
+
+	}
+
+	ast_gpio_write(&ast_gpio_gp[gp], set0, ast_gpio_gp[gp].debounce_offset);
+	ast_gpio_write(&ast_gpio_gp[gp], set1, ast_gpio_gp[gp].debounce_offset + 0x04);
+#endif
+}
+
+EXPORT_SYMBOL(ast_set_gpio_tolerant);
+
+/*
+ * We need to unmask the GPIO bank interrupt as soon as possible to
+ * avoid missing GPIO interrupts for other lines in the bank.
+ * Then we need to mask-read-clear-unmask the triggered GPIO lines
+ * in the bank to avoid missing nested interrupts for a GPIO line.
+ * If we wait to unmask individual GPIO lines in the bank after the
+ * line's interrupt handler has been run, we may miss some nested
+ * interrupts.
+ */
+static void 
+ast_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	u32 isr;
+	int i,j;
+	struct ast_gpio_bank *ast_gpio;
+
+	if(irq != IRQ_GPIO)
+		BUG();
+
+	GPIODBUG("ast_gpio_irq_handler %d \n ", irq);
+
+//	ast_gpio = get_irq_data(irq);
+
+//	GPIODBUG("[%s] ------\n ",ast_gpio->chip.label );
+	
+	desc->chip->ack(IRQ_GPIO);
+
+	for (i = 0; i < GPIO_PORT_NUM; i++) {
+		ast_gpio = &ast_gpio_gp[i];
+		isr = ast_gpio_read(ast_gpio, ast_gpio->int_sts_offset);
+		GPIODBUG("isr %x \n", isr);
+		isr = (isr >> (8 * ast_gpio->index)) & 0xff;
+		GPIODBUG("[%s] isr %x \n", ast_gpio->chip.label, isr);
+		if(isr != 0) {
+			//get gpio isr and --> to IRQ number ....
+			for (j=0; j<8;j++) {
+				if((1<<j) & isr) {
+					// dispach interrupt
+//					GPIODBUG("[%s] pin %d -> irq [%d]\n",ast_gpio->chip.label, j, j + IRQ_GPIO_CHAIN_START + (8 * i));
+					generic_handle_irq(j + IRQ_GPIO_CHAIN_START + (8 * i));
+				}
+			}
+//			GPIODBUG("isr -- ? %x \n",ast_gpio_read(ast_gpio, ast_gpio->int_sts_offset));
+		}		
+	}
+
+#if 0
+	while(1) {
+		isr = ast_gpio_read(ast_gpio, ast_gpio->int_sts_offset);
+		printk("isr %x \n", isr);
+		isr = isr >> (8 * ast_gpio->index);
+		//get gpio isr and --> to IRQ number ....
+		for (i=0; i<8;i++) {
+			if((1<<i) & isr) {
+				// dispach interrupt
+				printk("[%s] pin %d -> irq [%d]\n",ast_gpio->chip.label, i,i + IRQ_GPIO_CHAIN_START + (8 * ast_gpio->index));
+				generic_handle_irq(i + IRQ_GPIO_CHAIN_START + (8 * ast_gpio->index));
+			}
+		}
+		if(isr == 0)
+			break;
+	}
+#endif		
+	desc->chip->unmask(IRQ_GPIO);
+	/* now it may re-trigger */
+
+}
+
+static void ast_gpio_ack_irq(unsigned int irq)
+{
+	struct ast_gpio_bank *ast_gpio = get_irq_chip_data(irq);
+
+	unsigned int gpio_irq = irq - IRQ_GPIO_CHAIN_START;
+
+	gpio_irq = gpio_irq % 8;
+
+	GPIODBUG("irq [%d] : ast_gpio_ack_irq [%s] pin %d\n ",irq, ast_gpio->chip.label, gpio_irq);
+
+	GPIODBUG("write clr [%x] %x\n ",ast_gpio->int_sts_offset, 1<< (gpio_irq + (ast_gpio->index * 8)));
+		
+	ast_gpio_write(ast_gpio, 1<< (gpio_irq + (ast_gpio->index * 8)), ast_gpio->int_sts_offset);
+
+	GPIODBUG("read sts %x\n ",ast_gpio_read(ast_gpio, ast_gpio->int_sts_offset));
+
+}
+
+static void ast_gpio_mask_irq(unsigned int irq)
+{
+	struct ast_gpio_bank *ast_gpio = get_irq_chip_data(irq);
+	unsigned int gpio_irq = irq - IRQ_GPIO_CHAIN_START;
+	gpio_irq = gpio_irq%8;
+	
+
+	GPIODBUG("irq [%d] : ast_gpio_mask_irq [%s] pin %d\n ",irq, ast_gpio->chip.label, gpio_irq);
+
+	//disable irq
+	ast_gpio_write(ast_gpio, ast_gpio_read(ast_gpio, ast_gpio->int_en_offset) &
+			~(1<< (gpio_irq + (ast_gpio->index * 8))), ast_gpio->int_en_offset);
+}
+
+static void ast_gpio_unmask_irq(unsigned int irq)
+{
+	struct ast_gpio_bank *ast_gpio = get_irq_chip_data(irq);
+	unsigned int gpio_irq = irq - IRQ_GPIO_CHAIN_START;
+	gpio_irq = gpio_irq%8;	
+
+
+	GPIODBUG("irq[%d], [%s] pin %d\n",irq, ast_gpio->chip.label, gpio_irq);
+
+	//Enable IRQ ..
+	ast_gpio_write(ast_gpio, 1<< (gpio_irq + (ast_gpio->index * 8)), ast_gpio->int_sts_offset);
+
+	ast_gpio_write(ast_gpio, ast_gpio_read(ast_gpio, ast_gpio->int_en_offset) |
+			(1<< (gpio_irq + (ast_gpio->index * 8))), ast_gpio->int_en_offset);
+
+}
+
+static int
+ast_gpio_irq_type(unsigned int irq, unsigned int type)
+{
+	u32 type0, type1, type2;
+	struct ast_gpio_bank *ast_gpio;
+	int retval = 0;	
+	unsigned int gpio_irq = irq - IRQ_GPIO_CHAIN_START;
+	gpio_irq = gpio_irq%32;
+
+
+
+	GPIODBUG("ast_gpio_irq_type %d : %x \n",irq,type);
+	if (type & ~IRQ_TYPE_SENSE_MASK)
+		return -EINVAL;
+
+	ast_gpio = get_irq_chip_data(irq);
+
+	type0 = ast_gpio_read(ast_gpio, ast_gpio->int_type_offset);
+	type1 = ast_gpio_read(ast_gpio, ast_gpio->int_type_offset + 0x04);
+	type2 = ast_gpio_read(ast_gpio, ast_gpio->int_type_offset + 0x08);
+
+	switch(type) {
+		/* Edge rising type */
+		case IRQ_TYPE_EDGE_RISING:
+			type0 |=(1<<irq);
+			type1 &=~(1<<irq);
+			type2 &=~(1<<irq);
+			break;
+		/* Edge falling type */
+		case IRQ_TYPE_EDGE_FALLING:
+			type2 |=(1<<irq);
+			break;
+		case IRQ_TYPE_EDGE_BOTH:
+			type0 &=~(1<<irq);
+			type1 |=(1<<irq);
+			type2 &=~(1<<irq);
+			break;
+		case IRQ_TYPE_LEVEL_HIGH:
+			type0 |=(1<<irq);
+			type1 |=(1<<irq);
+			type2 &=~(1<<irq);
+			break;
+		case IRQ_TYPE_LEVEL_LOW:
+			type0 &=~(1<<irq);
+			type1 |=(1<<irq);
+			type2 &=~(1<<irq);
+			break;
+		default:
+			GPIODBUG("not support trigger");
+			return -EINVAL;
+			break;
+	}
+
+	ast_gpio_write(ast_gpio, type0, ast_gpio->int_type_offset);
+	ast_gpio_write(ast_gpio, type1, ast_gpio->int_type_offset + 0x04);
+	ast_gpio_write(ast_gpio, type2, ast_gpio->int_type_offset + 0x08);
+
+	return retval;
+
+}
+
+static struct irq_chip ast_gpio_irq_chip = {
+	.name		= "GPIO",
+	.ack		= ast_gpio_ack_irq,
+	.mask		= ast_gpio_mask_irq,
+	.unmask		= ast_gpio_unmask_irq,
+	.set_type	= ast_gpio_irq_type,
+};
+
+/*---------------------------------------------------------------------*/
+static int __init ast_gpio_init(void)
+{
+	int i,j;
+	struct ast_gpio_bank *ast_gpio;
+
+	GPIODBUG("gpio port num %d, total gpio pin : %d\n",
+		GPIO_PORT_NUM, ARCH_NR_GPIOS);
+
+	GPIODBUG("gpio chain start %d \n",IRQ_GPIO_CHAIN_START);
+	for (i = 0; i < GPIO_PORT_NUM; i++) {
+		ast_gpio = &ast_gpio_gp[i];
+
+		GPIODBUG("add gpio_chip [%s] : %d\n",ast_gpio->chip.label, i);
+
+#if 0		 
+		bank->chip.direction_input = ast_gpio_direction_input;
+		bank->chip.get = ast_gpio_get;
+		bank->chip.direction_output = ast_gpio_direction_output;
+		bank->chip.set = ast_gpio_set;
+
+		bank->chip.label = "gpio";
+#endif
+		ast_gpio->chip.base = i*8;
+		ast_gpio->chip.ngpio = 8;
+
+		gpiochip_add(&ast_gpio->chip);
+
+#if 1
+		//Set Level Trigger
+		ast_gpio_write(ast_gpio, 0xffffffff, ast_gpio->int_type_offset);
+		ast_gpio_write(ast_gpio, 0xffffffff, ast_gpio->int_type_offset + 0x04);
+		ast_gpio_write(ast_gpio, 0, ast_gpio->int_type_offset + 0x08);
+		//remove clear direction for keep orignal state
+//		ast_gpio_write(ast_gpio, 0, ast_gpio->dir_offset);
+		//Enable IRQ 
+//		ast_gpio_write(ast_gpio, 0xffffffff, ast_gpio->int_en_offset);
+		
+#endif
+
+		for(j=0;j<8;j++) {
+			GPIODBUG("inst chip data %d\n",i*8 + j + IRQ_GPIO_CHAIN_START);	
+			set_irq_chip_data(i*8 + j + IRQ_GPIO_CHAIN_START, ast_gpio);
+			set_irq_chip(i*8 + j + IRQ_GPIO_CHAIN_START, &ast_gpio_irq_chip);
+			set_irq_handler(i*8 + j + IRQ_GPIO_CHAIN_START, handle_level_irq);
+			set_irq_flags(i*8 + j + IRQ_GPIO_CHAIN_START, IRQF_VALID);
+		}
+		set_irq_chained_handler(IRQ_GPIO, ast_gpio_irq_handler);
+//		set_irq_chip_data(IRQ_GPIO, ast_gpio);
+//		set_irq_data(IRQ_GPIO, ast_gpio_gp[]);
+		
+		
+	}
+
+	return 0;
+	
+}
+
+core_initcall(ast_gpio_init);
+
+//arch_initcall(ast_gpio_init);
+
diff --git a/arch/arm/mach-aspeed/include/mach/aspeed_serial.h b/arch/arm/mach-aspeed/include/mach/aspeed_serial.h
new file mode 100644
index 0000000..33bf333
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/aspeed_serial.h
@@ -0,0 +1,61 @@
+/*
+ *  file : aspeed_serial.h
+ * 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_AST_SERIAL_H
+#define ASM_ARM_HARDWARE_AST_SERIAL_H
+
+#define UART_RBR            0x00    /* Receiver Buffer Register */
+#define UART_THR            0x00    /* Transmit Holding Register */
+#define UART_DLL            0x00    /* Divisor Latch Low Register */
+#define UART_DLH            0x04    /* Divisor Latch High Register */
+#define UART_IER            0x04    /* Interrupt Enable Register */
+#define UART_IIR            0x08    /* Interrupt Identity Register */
+#define UART_FCR            0x08    /* FIFO Control Register */
+#define UART_LCR            0x0C    /* Line Control Register */
+#define UART_MCR            0x10    /* Modem Control Register */
+#define UART_LSR            0x14    /* Line Status Register */
+#define UART_MSR            0x18    /* Modem Status Register */
+#define UART_SCR            0x1C    /* Scratch Register */
+
+/* Interrupt Enable Register */
+#define UART_IER_EMSI       0x08    /* Enable Modem Status Interrupt */
+#define UART_IER_ELSI       0x04    /* Enable Line Status Interrupt */
+#define UART_IER_ETEI       0x02    /* Enable Transmit Holding Empty Interrupt */
+#define UART_IER_ERDI       0X01    /* Enable Received Data Interrupt */
+
+/* FIFO Control Register */
+#define UART_FCR_XMITR      0x04    /* XMIT FIFO Reset */
+#define UART_FCR_RCVRR      0x02    /* RCVR FIFO Reset */
+#define UART_FCR_FIFOE      0x01    /* FIEO Enable */
+
+/* Line Control Register */
+#define UART_LCR_DLAB       0x80    /* Divisor Latch Address Bit */
+#define UART_LCR_BRK        0x40    /* Break Control */
+#define UART_LCR_EPS        0x10    /* Even Parity Select */
+#define UART_LCR_PEN        0x08    /* Parity Enable */
+#define UART_LCR_STOP       0x04    /* Stop Bit */
+#define UART_LCR_WLEN_MASK  0x03    /* bits per character mask */
+#define UART_LCR_WLEN_8     0x03    /* 8 bits per character */
+#define UART_LCR_WLEN_7     0x02    /* 7 bits per character */
+#define UART_LCR_WLEN_6     0x01    /* 6 bits per character */
+#define UART_LCR_WLEN_5     0x00    /* 5 bits per character */
+
+/* Line Status Register */
+#define UART_LSR_TEMT       0x40    /* Transmitter Empty */
+#define UART_LSR_THRE       0x20    /* Transmitter Holding Register Empty */
+#define UART_LSR_BE         0x10    /* Break Error */
+#define UART_LSR_FE         0x08    /* Framing Error */
+#define UART_LSR_PE         0x04    /* Parity Error */
+#define UART_LSR_OE         0x02    /* Overrun Error */
+#define UART_LSR_DR         0x01    /* Data Ready */
+#define UART_LSR_ANY        (UART_LSR_BE|UART_LSR_FE|UART_LSR_PE|UART_LSR_OE)
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast-uart-dma.h b/arch/arm/mach-aspeed/include/mach/ast-uart-dma.h
new file mode 100644
index 0000000..2ac2b41
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast-uart-dma.h
@@ -0,0 +1,86 @@
+/********************************************************************************
+* File Name     : ast-uart-dma.h
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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 AST_UART_DMA_H_INCLUDED
+#define AST_UART_DMA_H_INCLUDED
+
+
+#define	DMA_BUFF_SIZE				0x1000	//4096
+
+struct ast_uart_dma_data {
+		u8		chip_no;		//campain chip number 
+		u8		dma_ch;		//dma channel number 
+};
+
+
+/* enum ast_uart_chan_op
+ *
+ * operation codes passed to the DMA code by the user, and also used
+ * to inform the current channel owner of any changes to the system state
+*/
+
+enum ast_uart_chan_op {
+	AST_UART_DMAOP_TRIGGER,
+	AST_UART_DMAOP_STOP,
+};
+
+struct ast1070_dma_ch;
+
+/* ast_uart_dma_cbfn_t *  * buffer callback routine type */
+typedef void (*ast_uart_dma_cbfn_t)(struct ast1070_dma_ch *,void *dev_id, u16 len);
+
+struct uart_dma_desc {
+	u32	desc0;
+	u32	desc1;
+	u32	desc2;	
+	u32	desc3;	
+} __attribute__ ((aligned(16)));
+
+struct ast1070_dma_ch {
+	u8	ch_no;
+	u8 	direction;	
+	u8	enable;
+	u32	ctrl_offset;
+	u32	desc_offset;	
+	void	*priv;
+	struct uart_dma_desc 	*desc;
+	dma_addr_t	desc_dma_addr;	/* Mapped descr. table */
+	/* cdriver callbacks */
+	ast_uart_dma_cbfn_t	 callback_fn;	/* buffer done callback */
+};
+
+#define AST1070_UART_DMA_CH 		4
+
+struct ast1070_dma {
+	void __iomem		*reg_base;	
+	struct ast1070_dma_ch	dma_tx_ch[AST1070_UART_DMA_CH];
+	struct ast1070_dma_ch	dma_rx_ch[AST1070_UART_DMA_CH];	
+};
+
+
+/* ast_uart_dma_request  *  * request a dma channel exclusivley */
+extern int ast_uart_rx_dma_request(u8 node, u8 channel, ast_uart_dma_cbfn_t rtn, void *id);
+extern int ast_uart_tx_dma_request(u8 node, u8 channel, ast_uart_dma_cbfn_t rtn, void *id);
+
+/* ast_uart_dma_ctrl  *  * change the state of the dma channel */
+extern int ast_uart_rx_dma_ctrl(u8 node, u8 ch, enum ast_uart_chan_op op);
+extern int ast_uart_tx_dma_ctrl(u8 node, u8 ch, enum ast_uart_chan_op op);
+
+extern int ast_uart_rx_dma_enqueue(u8 node, u8 ch, dma_addr_t rx_buff, u16 len);
+extern int ast_uart_tx_dma_enqueue(u8 node, u8 ch, dma_addr_t tx_buff, u16 len);
+
+
+
+#endif
+
diff --git a/arch/arm/mach-aspeed/include/mach/ast1070_irqs.h b/arch/arm/mach-aspeed/include/mach/ast1070_irqs.h
new file mode 100644
index 0000000..0774417
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast1070_irqs.h
@@ -0,0 +1,142 @@
+/*
+ *  arch/arm/plat-aspeed/include/plat/irqs.h
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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 _AST1070_IRQS_H_
+#define _AST1070_IRQS_H_                 1
+
+#define IRQ_C0_VIC_CHAIN					IRQ_EXT0
+#define IRQ_C0_VIC_CHAIN_START			(AST_VIC_NUM)
+
+#define IRQ_C1_VIC_CHAIN					IRQ_EXT1
+#define IRQ_C1_VIC_CHAIN_START			(IRQ_C0_VIC_CHAIN_START + AST_CVIC_NUM)
+
+#define IRQ_C2_VIC_CHAIN					IRQ_EXT2
+#define IRQ_C2_VIC_CHAIN_START			(IRQ_C1_VIC_CHAIN_START + AST_CVIC_NUM)
+
+#define IRQ_C3_VIC_CHAIN					IRQ_EXT3
+#define IRQ_C3_VIC_CHAIN_START			(IRQ_C2_VIC_CHAIN_START + AST_CVIC_NUM)
+
+#define AST_CVIC_NUM 					25
+
+#define IRQ_C0_N1_KCS                     (IRQ_C0_VIC_CHAIN_START + 0)
+#define IRQ_C0_N1_UART                    (IRQ_C0_VIC_CHAIN_START + 1)
+#define IRQ_C0_N1_MAILBOX                 (IRQ_C0_VIC_CHAIN_START + 2)
+#define IRQ_C0_N1_PORT80                  (IRQ_C0_VIC_CHAIN_START + 3)
+#define IRQ_C0_N1_RESET                   (IRQ_C0_VIC_CHAIN_START + 4)
+#define IRQ_C0_N2_KCS                     (IRQ_C0_VIC_CHAIN_START + 5)
+#define IRQ_C0_N2_UART                    (IRQ_C0_VIC_CHAIN_START + 6)
+#define IRQ_C0_N2_MAILBOX                 (IRQ_C0_VIC_CHAIN_START + 7)
+#define IRQ_C0_N2_PORT80                  (IRQ_C0_VIC_CHAIN_START + 8)
+#define IRQ_C0_N2_RESET                   (IRQ_C0_VIC_CHAIN_START + 9)
+#define IRQ_C0_N3_KCS                     (IRQ_C0_VIC_CHAIN_START + 10)
+#define IRQ_C0_N3_UART                    (IRQ_C0_VIC_CHAIN_START + 11)
+#define IRQ_C0_N3_MAILBOX                 (IRQ_C0_VIC_CHAIN_START + 12)
+#define IRQ_C0_N3_PORT80                  (IRQ_C0_VIC_CHAIN_START + 13)
+#define IRQ_C0_N3_RESET                   (IRQ_C0_VIC_CHAIN_START + 14)
+#define IRQ_C0_N4_KCS                     (IRQ_C0_VIC_CHAIN_START + 15)
+#define IRQ_C0_N4_UART                    (IRQ_C0_VIC_CHAIN_START + 16)
+#define IRQ_C0_N4_MAILBOX                 (IRQ_C0_VIC_CHAIN_START + 17)
+#define IRQ_C0_N4_PORT80                  (IRQ_C0_VIC_CHAIN_START + 18)
+#define IRQ_C0_N4_RESET                   (IRQ_C0_VIC_CHAIN_START + 19)
+#define IRQ_C0_N1_UART_DMA                (IRQ_C0_VIC_CHAIN_START + 20)
+#define IRQ_C0_N2_UART_DMA                (IRQ_C0_VIC_CHAIN_START + 21)
+#define IRQ_C0_N3_UART_DMA                (IRQ_C0_VIC_CHAIN_START + 22)
+#define IRQ_C0_N4_UART_DMA                (IRQ_C0_VIC_CHAIN_START + 23)
+#define IRQ_C0_I2C						(IRQ_C0_VIC_CHAIN_START + 24)
+
+#define IRQ_C1_N1_KCS                     (IRQ_C1_VIC_CHAIN_START + 0)
+#define IRQ_C1_N1_UART                    (IRQ_C1_VIC_CHAIN_START + 1)
+#define IRQ_C1_N1_MAILBOX                 (IRQ_C1_VIC_CHAIN_START + 2)
+#define IRQ_C1_N1_PORT80                  (IRQ_C1_VIC_CHAIN_START + 3)
+#define IRQ_C1_N1_RESET                   (IRQ_C1_VIC_CHAIN_START + 4)
+#define IRQ_C1_N2_KCS                     (IRQ_C1_VIC_CHAIN_START + 5)
+#define IRQ_C1_N2_UART                    (IRQ_C1_VIC_CHAIN_START + 6)
+#define IRQ_C1_N2_MAILBOX                 (IRQ_C1_VIC_CHAIN_START + 7)
+#define IRQ_C1_N2_PORT80                  (IRQ_C1_VIC_CHAIN_START + 8)
+#define IRQ_C1_N2_RESET                   (IRQ_C1_VIC_CHAIN_START + 9)
+#define IRQ_C1_N3_KCS                     (IRQ_C1_VIC_CHAIN_START + 10)
+#define IRQ_C1_N3_UART                    (IRQ_C1_VIC_CHAIN_START + 11)
+#define IRQ_C1_N3_MAILBOX                 (IRQ_C1_VIC_CHAIN_START + 12)
+#define IRQ_C1_N3_PORT80                  (IRQ_C1_VIC_CHAIN_START + 13)
+#define IRQ_C1_N3_RESET                   (IRQ_C1_VIC_CHAIN_START + 14)
+#define IRQ_C1_N4_KCS                     (IRQ_C1_VIC_CHAIN_START + 15)
+#define IRQ_C1_N4_UART                    (IRQ_C1_VIC_CHAIN_START + 16)
+#define IRQ_C1_N4_MAILBOX                 (IRQ_C1_VIC_CHAIN_START + 17)
+#define IRQ_C1_N4_PORT80                  (IRQ_C1_VIC_CHAIN_START + 18)
+#define IRQ_C1_N4_RESET                   (IRQ_C1_VIC_CHAIN_START + 19)
+#define IRQ_C1_N1_UART_DMA                (IRQ_C1_VIC_CHAIN_START + 20)
+#define IRQ_C1_N2_UART_DMA                (IRQ_C1_VIC_CHAIN_START + 21)
+#define IRQ_C1_N3_UART_DMA                (IRQ_C1_VIC_CHAIN_START + 22)
+#define IRQ_C1_N4_UART_DMA                (IRQ_C1_VIC_CHAIN_START + 23)
+#define IRQ_C1_I2C						(IRQ_C1_VIC_CHAIN_START + 24)
+
+#define IRQ_C2_N1_KCS                     (IRQ_C2_VIC_CHAIN_START + 0)
+#define IRQ_C2_N1_UART                    (IRQ_C2_VIC_CHAIN_START + 1)
+#define IRQ_C2_N1_MAILBOX                 (IRQ_C2_VIC_CHAIN_START + 2)
+#define IRQ_C2_N1_PORT80                  (IRQ_C2_VIC_CHAIN_START + 3)
+#define IRQ_C2_N1_RESET                   (IRQ_C2_VIC_CHAIN_START + 4)
+#define IRQ_C2_N2_KCS                     (IRQ_C2_VIC_CHAIN_START + 5)
+#define IRQ_C2_N2_UART                    (IRQ_C2_VIC_CHAIN_START + 6)
+#define IRQ_C2_N2_MAILBOX                 (IRQ_C2_VIC_CHAIN_START + 7)
+#define IRQ_C2_N2_PORT80                  (IRQ_C2_VIC_CHAIN_START + 8)
+#define IRQ_C2_N2_RESET                   (IRQ_C2_VIC_CHAIN_START + 9)
+#define IRQ_C2_N3_KCS                     (IRQ_C2_VIC_CHAIN_START + 10)
+#define IRQ_C2_N3_UART                    (IRQ_C2_VIC_CHAIN_START + 11)
+#define IRQ_C2_N3_MAILBOX                 (IRQ_C2_VIC_CHAIN_START + 12)
+#define IRQ_C2_N3_PORT80                  (IRQ_C2_VIC_CHAIN_START + 13)
+#define IRQ_C2_N3_RESET                   (IRQ_C2_VIC_CHAIN_START + 14)
+#define IRQ_C2_N4_KCS                     (IRQ_C2_VIC_CHAIN_START + 15)
+#define IRQ_C2_N4_UART                    (IRQ_C2_VIC_CHAIN_START + 16)
+#define IRQ_C2_N4_MAILBOX                 (IRQ_C2_VIC_CHAIN_START + 17)
+#define IRQ_C2_N4_PORT80                  (IRQ_C2_VIC_CHAIN_START + 18)
+#define IRQ_C2_N4_RESET                   (IRQ_C2_VIC_CHAIN_START + 19)
+#define IRQ_C2_N1_UART_DMA                (IRQ_C2_VIC_CHAIN_START + 20)
+#define IRQ_C2_N2_UART_DMA                (IRQ_C2_VIC_CHAIN_START + 21)
+#define IRQ_C2_N3_UART_DMA                (IRQ_C2_VIC_CHAIN_START + 22)
+#define IRQ_C2_N4_UART_DMA                (IRQ_C2_VIC_CHAIN_START + 23)
+#define IRQ_C2_I2C						(IRQ_C2_VIC_CHAIN_START + 24)
+
+#define IRQ_C3_N1_KCS                     (IRQ_C3_VIC_CHAIN_START + 0)
+#define IRQ_C3_N1_UART                    (IRQ_C3_VIC_CHAIN_START + 1)
+#define IRQ_C3_N1_MAILBOX                 (IRQ_C3_VIC_CHAIN_START + 2)
+#define IRQ_C3_N1_PORT80                  (IRQ_C3_VIC_CHAIN_START + 3)
+#define IRQ_C3_N1_RESET                   (IRQ_C3_VIC_CHAIN_START + 4)
+#define IRQ_C3_N2_KCS                     (IRQ_C3_VIC_CHAIN_START + 5)
+#define IRQ_C3_N2_UART                    (IRQ_C3_VIC_CHAIN_START + 6)
+#define IRQ_C3_N2_MAILBOX                 (IRQ_C3_VIC_CHAIN_START + 7)
+#define IRQ_C3_N2_PORT80                  (IRQ_C3_VIC_CHAIN_START + 8)
+#define IRQ_C3_N2_RESET                   (IRQ_C3_VIC_CHAIN_START + 9)
+#define IRQ_C3_N3_KCS                     (IRQ_C3_VIC_CHAIN_START + 10)
+#define IRQ_C3_N3_UART                    (IRQ_C3_VIC_CHAIN_START + 11)
+#define IRQ_C3_N3_MAILBOX                 (IRQ_C3_VIC_CHAIN_START + 12)
+#define IRQ_C3_N3_PORT80                  (IRQ_C3_VIC_CHAIN_START + 13)
+#define IRQ_C3_N3_RESET                   (IRQ_C3_VIC_CHAIN_START + 14)
+#define IRQ_C3_N4_KCS                     (IRQ_C3_VIC_CHAIN_START + 15)
+#define IRQ_C3_N4_UART                    (IRQ_C3_VIC_CHAIN_START + 16)
+#define IRQ_C3_N4_MAILBOX                 (IRQ_C3_VIC_CHAIN_START + 17)
+#define IRQ_C3_N4_PORT80                  (IRQ_C3_VIC_CHAIN_START + 18)
+#define IRQ_C3_N4_RESET                   (IRQ_C3_VIC_CHAIN_START + 19)
+#define IRQ_C3_N1_UART_DMA                (IRQ_C3_VIC_CHAIN_START + 20)
+#define IRQ_C3_N2_UART_DMA                (IRQ_C3_VIC_CHAIN_START + 21)
+#define IRQ_C3_N3_UART_DMA                (IRQ_C3_VIC_CHAIN_START + 22)
+#define IRQ_C3_N4_UART_DMA                (IRQ_C3_VIC_CHAIN_START + 23)
+#define IRQ_C3_I2C						(IRQ_C3_VIC_CHAIN_START + 24)
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast1070_platform.h b/arch/arm/mach-aspeed/include/mach/ast1070_platform.h
new file mode 100644
index 0000000..feefd91
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast1070_platform.h
@@ -0,0 +1,100 @@
+/*
+ * 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 _AST1070_PLATFORM_H_
+#define _AST1070_PLATFORM_H_                 1
+
+#define AST_C0_BASE                    		(AST_LPC_BRIDGE)
+
+#define AST_C0_UART0_BASE                    (AST_C0_BASE)	/* Companion UART1 */
+#define AST_C0_UART1_BASE                    (AST_C0_BASE + 0x400)	/* Companion UART2 */
+#define AST_C0_UART2_BASE                    (AST_C0_BASE + 0x800)	/* Companion UART3 */
+#define AST_C0_UART3_BASE                    (AST_C0_BASE + 0xc00)	/* Companion UART4 */
+#define AST_C0_LPC0_BASE                     (AST_C0_BASE + 0x1000)	/* Companion LPC1 */
+#define AST_C0_LPC1_BASE                     (AST_C0_BASE + 0x1400)	/* Companion LPC2 */
+#define AST_C0_LPC2_BASE                     (AST_C0_BASE + 0x1800)	/* Companion LPC3 */
+#define AST_C0_LPC3_BASE                     (AST_C0_BASE + 0x1c00)	/* Companion LPC4 */
+#define AST_C0_SCU_BASE                      (AST_C0_BASE + 0x2000)	/* Companion SCU */
+#define AST_C0_VIC_BASE                      (AST_C0_BASE + 0x2400)	/* Companion VIC */
+#define AST_C0_LPC_SLAVE_BASE                (AST_C0_BASE + 0x2c00)	/* Companion LPC SlLAVE */
+#define AST_C0_I2C_BASE                      (AST_C0_BASE + 0x3000)	/* Companion I2C */
+#define AST_C0_SPI_BASE                      (AST_C0_BASE + 0x4000)	/* Companion SPI */
+#define AST_C0_LPC_SPI_BASE                  (AST_C0_BASE + 0x4400)	/* Companion LPC SPI */
+#define AST_C0_UART_DMA_BASE                 (AST_C0_BASE + 0x4800)	/* Companion UART DMA */
+#define AST_C0_SPI_CONTROL_BASE              (AST_C0_BASE + 0x4c00)	/* Companion SPI CONTROL */
+#define AST_C0_SPI_SHADOW_SRAM_BASE          (AST_C0_BASE + 0x5000)	/* Companion SPI SHADOW SRAM */
+
+#define AST_C1_BASE                    		(AST_LPC_BRIDGE + 0x10000)	
+
+#define AST_C1_UART0_BASE                    (AST_C1_BASE)			/* Companion UART1 */
+#define AST_C1_UART1_BASE                    (AST_C1_BASE + 0x400)	/* Companion UART2 */
+#define AST_C1_UART2_BASE                    (AST_C1_BASE + 0x800)	/* Companion UART3 */
+#define AST_C1_UART3_BASE                    (AST_C1_BASE + 0xc00)	/* Companion UART4 */
+#define AST_C1_LPC0_BASE                     (AST_C1_BASE + 0x1000)	/* Companion LPC1 */
+#define AST_C1_LPC1_BASE                     (AST_C1_BASE + 0x1400)	/* Companion LPC2 */
+#define AST_C1_LPC2_BASE                     (AST_C1_BASE + 0x1800)	/* Companion LPC3 */
+#define AST_C1_LPC3_BASE                     (AST_C1_BASE + 0x1c00)	/* Companion LPC4 */
+#define AST_C1_SCU_BASE                      (AST_C1_BASE + 0x2000)	/* Companion SCU */
+#define AST_C1_VIC_BASE                      (AST_C1_BASE + 0x2400)	/* Companion VIC */
+#define AST_C1_LPC_SLAVE_BASE                (AST_C1_BASE + 0x2c00)	/* Companion LPC SlLAVE */
+#define AST_C1_I2C_BASE                      (AST_C1_BASE + 0x3000)	/* Companion I2C */
+#define AST_C1_SPI_BASE                      (AST_C1_BASE + 0x4000)	/* Companion SPI */
+#define AST_C1_LPC_SPI_BASE                  (AST_C1_BASE + 0x4400)	/* Companion LPC SPI */
+#define AST_C1_UART_DMA_BASE                 (AST_C1_BASE + 0x4800)	/* Companion UART DMA */
+#define AST_C1_SPI_CONTROL_BASE              (AST_C1_BASE + 0x4c00)	/* Companion SPI CONTROL */
+#define AST_C1_SPI_SHADOW_SRAM_BASE          (AST_C1_BASE + 0x5000)	/* Companion SPI SHADOW SRAM */
+
+#define AST_C2_BASE                    		(AST_LPC_BRIDGE + 0x20000)	
+
+#define AST_C2_UART0_BASE                    (AST_C2_BASE)			/* Companion UART1 */
+#define AST_C2_UART1_BASE                    (AST_C2_BASE + 0x400)	/* Companion UART2 */
+#define AST_C2_UART2_BASE                    (AST_C2_BASE + 0x800)	/* Companion UART3 */
+#define AST_C2_UART3_BASE                    (AST_C2_BASE + 0xc00)	/* Companion UART4 */
+#define AST_C2_LPC1_BASE                     (AST_C2_BASE + 0x1000)	/* Companion LPC1 */
+#define AST_C2_LPC2_BASE                     (AST_C2_BASE + 0x1400)	/* Companion LPC2 */
+#define AST_C2_LPC3_BASE                     (AST_C2_BASE + 0x1800)	/* Companion LPC3 */
+#define AST_C2_LPC4_BASE                     (AST_C2_BASE + 0x1c00)	/* Companion LPC4 */
+#define AST_C2_SCU_BASE                      (AST_C2_BASE + 0x2000)	/* Companion SCU */
+#define AST_C2_VIC_BASE                      (AST_C2_BASE + 0x2400)	/* Companion VIC */
+#define AST_C2_LPC_SLAVE_BASE                (AST_C2_BASE + 0x2c00)	/* Companion LPC SlLAVE */
+#define AST_C2_I2C_BASE                      (AST_C2_BASE + 0x3000)	/* Companion I2C */
+#define AST_C2_SPI_BASE                      (AST_C2_BASE + 0x4000)	/* Companion SPI */
+#define AST_C2_LPC_SPI_BASE                  (AST_C2_BASE + 0x4400)	/* Companion LPC SPI */
+#define AST_C2_UART_DMA_BASE                 (AST_C2_BASE + 0x4800)	/* Companion UART DMA */
+#define AST_C2_SPI_CONTROL_BASE              (AST_C2_BASE + 0x4c00)	/* Companion SPI CONTROL */
+#define AST_C2_SPI_SHADOW_SRAM_BASE          (AST_C2_BASE + 0x5000)	/* Companion SPI SHADOW SRAM */
+
+#define AST_C3_BASE                    		(AST_LPC_BRIDGE + 0x30000)	
+
+#define AST_C3_UART0_BASE                    (AST_C3_BASE)			/* Companion UART1 */
+#define AST_C3_UART1_BASE                    (AST_C3_BASE + 0x400)	/* Companion UART2 */
+#define AST_C3_UART2_BASE                    (AST_C3_BASE + 0x800)	/* Companion UART3 */
+#define AST_C3_UART3_BASE                    (AST_C3_BASE + 0xc00)	/* Companion UART4 */
+#define AST_C3_LPC0_BASE                     (AST_C3_BASE + 0x1000)	/* Companion LPC1 */
+#define AST_C3_LPC1_BASE                     (AST_C3_BASE + 0x1400)	/* Companion LPC2 */
+#define AST_C3_LPC2_BASE                     (AST_C3_BASE + 0x1800)	/* Companion LPC3 */
+#define AST_C3_LPC3_BASE                     (AST_C3_BASE + 0x1c00)	/* Companion LPC4 */
+#define AST_C3_SCU_BASE                      (AST_C3_BASE + 0x2000)	/* Companion SCU */
+#define AST_C3_VIC_BASE                      (AST_C3_BASE + 0x2400)	/* Companion VIC */
+#define AST_C3_LPC_SLAVE_BASE                (AST_C3_BASE + 0x2c00)	/* Companion LPC SlLAVE */
+#define AST_C3_I2C_BASE                      (AST_C3_BASE + 0x3000)	/* Companion I2C */
+#define AST_C3_SPI_BASE                      (AST_C3_BASE + 0x4000)	/* Companion SPI */
+#define AST_C3_LPC_SPI_BASE                  (AST_C3_BASE + 0x4400)	/* Companion LPC SPI */
+#define AST_C3_UART_DMA_BASE                 (AST_C3_BASE + 0x4800)	/* Companion UART DMA */
+#define AST_C3_SPI_CONTROL_BASE              (AST_C3_BASE + 0x4c00)	/* Companion SPI CONTROL */
+#define AST_C3_SPI_SHADOW_SRAM_BASE          (AST_C3_BASE + 0x5000)	/* Companion SPI SHADOW SRAM */
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast1520_irqs.h b/arch/arm/mach-aspeed/include/mach/ast1520_irqs.h
new file mode 100644
index 0000000..3ebc91b
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast1520_irqs.h
@@ -0,0 +1,107 @@
+/*
+ *  arch/arm/plat-aspeed/include/plat/irqs.h
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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 _AST1520_IRQS_H_
+#define _AST1520_IRQS_H_                 1
+
+
+#ifdef CONFIG_PCIE
+#define NR_IRQS					(ARCH_NR_GPIOS +ARCH_NR_PCIE + AST_VIC_NUM)
+
+//--------------GPIO ---------------------------------------------------------------
+#define ARCH_NR_GPIOS 			(GPIO_PORT_NUM*8)
+#define IRQ_GPIO_CHAIN_START	AST_VIC_NUM
+//------------------- ---------------------------------------------------------------
+
+#define ARCH_NR_PCIE			5
+#define IRQ_PCIE_CHAIN			IRQ_PCIE
+#define IRQ_PCIE_CHAIN_START	(ARCH_NR_GPIOS + AST_VIC_NUM)
+
+#define IRQ_PCIE_INTA			(IRQ_PCIE_CHAIN_START)
+#define IRQ_PCIE_INTB			(IRQ_PCIE_CHAIN_START + 1)
+#define IRQ_PCIE_INTC			(IRQ_PCIE_CHAIN_START + 2)
+#define IRQ_PCIE_INTD			(IRQ_PCIE_CHAIN_START + 3)
+#define IRQ_PCIE_MSI0			(IRQ_PCIE_INTD + 1)		// support max 32 MSI
+
+#else
+#define NR_IRQS                         (AST_VIC_NUM + ARCH_NR_GPIOS)
+//--------------GPIO ---------------------------------------------------------------
+#define ARCH_NR_GPIOS 					(GPIO_PORT_NUM*8)
+#define IRQ_GPIO_CHAIN_START			AST_VIC_NUM
+//------------------- ---------------------------------------------------------------
+#endif
+
+#define AST_VIC_NUM			51
+
+//#define IRQ_SDRAM_ECC					0
+//#define IRQ_MIC							1
+#define IRQ_MAC0						2			/* MAC 1 interrupt */
+//#define IRQ_MAC1						3			/* MAC 2 interrupt */
+#define IRQ_CRYPTO						4
+#define IRQ_USB20_HUB					5
+#define IRQ_EHCI						5
+#define IRQ_XDMA						6
+#define IRQ_VIDEO						7
+//#define IRQ_LPC							8
+#define IRQ_UART1						9			/* UART 1 interrupt */
+#define IRQ_UART0						10			/* UART 3 interrupt */
+//11 Reserved
+#define IRQ_I2C							12
+//#define IRQ_UDC11						13
+#define IRQ_UHCI						14
+//#define IRQ_PECI						15
+#define IRQ_TIMER0						16			/* TIMER 1 interrupt */
+#define IRQ_TIMER1						17			/* TIMER 2 interrupt */
+#define IRQ_TIMER2						18			/* TIMER 3 interrupt */
+//#define IRQ_SMC							19
+#define IRQ_GPIO						20
+#define IRQ_SCU							21
+#define IRQ_RTC							22
+//23 , 24 reserverd 
+#define IRQ_CRT							25
+#define IRQ_SDHC						26
+#define IRQ_WDT							27
+#define IRQ_TACHO						28
+#define IRQ_2D							29
+#define IRQ_SYS_WAKEUP					30
+//#define IRQ_ADC							31
+#define IRQ_UART2						32			/* UART 2 interrupt */
+//#define IRQ_UART2						33			/* UART 3 interrupt */
+//#define IRQ_UART3						34			/* UART 4 interrupt */
+//#define IRQ_TIMER3						35			/* TIMER 4 interrupt */
+//#define IRQ_TIMER4						36
+//#define IRQ_TIMER5						37
+//#define IRQ_TIMER6						38
+//#define IRQ_TIMER7						39			/* TIMER 8 interrupt */
+//#define IRQ_SGPIO_MASTER				40
+//#define IRQ_SGPIO_SLAVE					41
+#define IRQ_PCIE						41
+
+#define IRQ_MCTP						42
+//#define IRQ_JTAG						43
+#define IRQ_PS2							44
+#define IRQ_CPU1						45
+//#define IRQ_MAILBOX						46
+#define IRQ_EXT0_GPIOL1					47
+#define IRQ_EXT1_GPIOL3					48
+#define IRQ_EXT2_GPIOM3					49
+#define IRQ_EXT3_GPIOM3					50
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast1520_platform.h b/arch/arm/mach-aspeed/include/mach/ast1520_platform.h
new file mode 100644
index 0000000..daded5d
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast1520_platform.h
@@ -0,0 +1,61 @@
+/*
+ * 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 _AST1520_PLATFORM_H_
+#define _AST1520_PLATFORM_H_                 1
+
+#define AST_SRAM_SIZE					(SZ_8K)
+
+#define AST_AHB_CTRL_BASE            0x1E600000	/* AHB CONTROLLER */
+
+#define AST_SPI_BASE        				0x1E620000	/* SPI CONTROLLER */
+
+#define AST_MAC0_BASE                      0x1E660000	/* MAC1 */ 
+
+#define AST_USB20_BASE                    	0x1E6A0000	/* USB 2.0 VIRTUAL HUB CONTROLLER */
+#define AST_EHCI_BASE                		0x1E6A1000	/* USB 2.0 HOST CONTROLLER */
+#define AST_UHCI_BASE                		0x1E6B0000	/* USB 1.1 HOST CONTROLLER */
+#define AST_VIC_BASE                       	0x1E6C0000	/* VIC */
+#define AST_SDMC_BASE                       0x1E6E0000	/* MMC SDRAM*/
+#define AST_SCU_BASE                       	0x1E6E2000	/* SCU */
+#define AST_CRYPTO_BASE                    	0x1E6E3000	/* Crypto */
+
+#define AST_I2S_BASE	                   0x1E6E5000	/* I2S */
+#define AST_GRAPHIC_BASE                   0x1E6E6000	/* Graphics */
+#define AST_XDMA_BASE                      0x1E6E7000	/* XDMA */
+#define AST_MCTP_BASE                      0x1E6E8000	/* MCTP */
+#define AST_PCIE_BASE 						0x1E6ED000	/* PCIE */
+
+#define AST_VIDEO_BASE                     0x1E700000	/* VIDEO ENGINE */
+#define AST_SRAM_BASE                      0x1E720000	/* SRAM */
+#define AST_SDHC_BASE                        0x1E740000	/* SD */
+#define AST_2D_BASE                        0x1E760000	/* 2D */
+#define AST_GPIO_BASE                      0x1E780000	/* GPIO */
+#define AST_RTC_BASE                       0x1E781000	/* RTC */
+#define AST_TIMER_BASE                     0x1E782000	/* TIMER #0~2*/
+#define AST_UART1_BASE                     0x1E783000	/* UART1 */
+#define AST_UART0_BASE                     0x1E784000	/* UART3 */
+#define AST_WDT_BASE                       0x1E785000	/* WDT */
+
+#define AST_I2C_BASE                       0x1E78A000	/* I2C */
+#define AST_UART2_BASE                     0x1E78D000	/* UART2 */
+
+#define AST_SPI0_MEM							0x20000000
+
+#define AST_PCIE_WIN_BASE				0x70000000
+#define AST_PCIE_WIN_SIZE				0x01000000
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast2000_irqs.h b/arch/arm/mach-aspeed/include/mach/ast2000_irqs.h
new file mode 100644
index 0000000..50aece9
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast2000_irqs.h
@@ -0,0 +1,64 @@
+/*
+ *  arch/arm/plat-aspeed/include/plat/irqs.h
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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 _AST2000_IRQS_H_
+#define _AST2000_IRQS_H_                 1
+
+#define NR_IRQS                         (AST_VIC_NUM + ARCH_NR_GPIOS)
+//--------------GPIO ---------------------------------------------------------------
+#define ARCH_NR_GPIOS 					(GPIO_PORT_NUM*8)
+#define IRQ_GPIO_CHAIN_START			AST_VIC_NUM
+
+#define AST_VIC_NUM			32
+
+#define IRQ_SPI							0
+#define IRQ_UART0						1
+#define IRQ_UART1						2
+#define IRQ_TIMER0						3
+#define IRQ_TIMER1						4
+#define IRQ_TIMER2						5
+#define IRQ_RTC							6
+#define IRQ_MAC0						7
+#define IRQ_GPIO_B0						8
+#define IRQ_UDC							9
+#define IRQ_PCI							10
+#define IRQ_GPIO_B1						11
+#define IRQ_GPIO_B2						12
+#define IRQ_GPIO_B3						13
+#define IRQ_LPC							14
+#define IRQ_I2C							15
+#define IRQ_USB11						16
+#define IRQ_VIDEO						17
+#define IRQ_CRYPTO						18
+#define IRQ_SCU							19
+#define IRQ_GPIO_B4						20
+#define IRQ_GPIO_B5						21
+#define IRQ_GPIO_B6						22
+#define IRQ_GPIO_A0						23
+#define IRQ_GPIO_A1						24
+#define IRQ_GPIO_A2						25
+#define IRQ_GPIO_A3						26
+#define IRQ_HDMA						27
+#define IRQ_GPIO_A4						28
+#define IRQ_GPIO_A5						29
+#define IRQ_GPIO_A6						30
+#define IRQ_WDT							31
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast2000_platform.h b/arch/arm/mach-aspeed/include/mach/ast2000_platform.h
new file mode 100644
index 0000000..ff34f5b
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast2000_platform.h
@@ -0,0 +1,40 @@
+/*
+ * 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 _AST2000_PLATFORM_H_
+#define _AST2000_PLATFORM_H_                 1
+
+#define AST_MAC0_BASE                      0x19c80000	/* MAC1 */ 
+#define AST_CRYPTO_BASE                    0x1E6E0040	/* Crypto */
+#define AST_UDC11_BASE                     0x1E6E0080	/* USB11 */
+#define AST_SCU0_BASE                      0x1E6E0100	/* SCU1 */
+#define AST_LPC_BASE                       0x1E6E0400	/* LPC */
+#define AST_I2C_BASE                       0x1E6E0800	/* I2C */
+//---//
+#define AST_VIDEO_BASE                     0x1E700000	/* VIDEO ENGINE */
+#define AST_AHB_TO_PBUS_BASE               0x1E720000	/* APB -> PBUS */
+//...//
+#define AST_HDMA_BASE	                  0x1E7c0000	/* HDMA */
+#define AST_TIMER_BASE	                  0x1E800000	/* TIMER0/1/2 */
+#define AST_RTC_BASE		                  0x1E820000	/* RTC */
+#define AST_UART0_BASE	                  0x1E840000	/* UART0 */
+#define AST_UART1_BASE	                  0x1E860000	/* UART1 */
+#define AST_SPI_BASE		                  0x1E880000	/* SPI */
+#define AST_GPIO_BASE	                  0x1E8A0000	/* GPIO */
+#define AST_WDT_BASE		                  0x1E8C0000	/* WDT */
+#define AST_SCU0_BASE                      0x1E8E000c	/* SCU2 */
+ 
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast2100_irqs.h b/arch/arm/mach-aspeed/include/mach/ast2100_irqs.h
new file mode 100644
index 0000000..8513909
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast2100_irqs.h
@@ -0,0 +1,64 @@
+/*
+ *  arch/arm/plat-aspeed/include/plat/irqs.h
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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 _AST2100_IRQS_H_
+#define _AST2100_IRQS_H_                 1
+
+
+#define NR_IRQS                         (AST_VIC_NUM + ARCH_NR_GPIOS)
+//--------------GPIO ---------------------------------------------------------------
+#define ARCH_NR_GPIOS 					(GPIO_PORT_NUM*8)
+#define IRQ_GPIO_CHAIN_START			AST_VIC_NUM
+
+#define AST_VIC_NUM			32
+#define IRQ_SDRAM_ECC					0
+#define IRQ_MIC							1
+#define IRQ_MAC0						2			/* MAC 1 interrupt */
+#define IRQ_MAC1						3			/* MAC 2 interrupt */
+#define IRQ_CRYPTO						4
+#define IRQ_USB20_HUB					5
+#define IRQ_EHCI					5
+#define IRQ_XDMA						6
+#define IRQ_VIDEO						7
+#define IRQ_LPC							8
+#define IRQ_UART0						9			/* UART 1 interrupt */
+#define IRQ_UART1						10			/* UART 2 interrupt */
+//11 reserved 
+#define IRQ_I2C							12
+#define IRQ_UDC11					13
+//14 reserved 
+#define IRQ_PECI						15
+#define IRQ_TIMER0						16			/* TIMER 1 interrupt */
+#define IRQ_TIMER1						17			/* TIMER 2 interrupt */
+#define IRQ_TIMER2						18			/* TIMER 3 interrupt */
+#define IRQ_SMC							19
+#define IRQ_GPIO						20
+#define IRQ_SCU							21
+#define IRQ_RTC_SEC						22
+#define IRQ_RTC_DAY						23
+#define IRQ_RTC_HOUR					24
+#define IRQ_RTC_MIN						25
+#define IRQ_RTC							26
+#define IRQ_WDT							27
+#define IRQ_TACHO						28
+#define IRQ_2D							29
+#define IRQ_PCI							30
+#define IRQ_AHBC						31
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast2100_platform.h b/arch/arm/mach-aspeed/include/mach/ast2100_platform.h
new file mode 100644
index 0000000..6d59ca4
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast2100_platform.h
@@ -0,0 +1,56 @@
+/*
+ * 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 _AST2100_PLATFORM_H_
+#define _AST2100_PLATFORM_H_                 1
+
+#define AST_OLD_SMC_BASE						0x10000000		/*Legacy BMC Static Memory */
+#define AST_OLD_SMC_CTRL_BASE				0x16000000		/*Legacy BMC Static Memory Ctrl*/
+
+#define AST_AHB_CTRL_BASE            0x1E600000	/* AHB CONTROLLER */
+
+#define AST_MIC_BASE                       0x1E640000	/* MIC CONTROLLER */
+#define AST_MAC1_BASE                      0x1E660000	/* MAC1 */ 
+#define AST_MAC2_BASE                      0x1E680000	/* MAC2 */
+
+#define AST_USB20_BASE                     0x1E6A0000	/* USB 2.0 VIRTUAL HUB CONTROLLER */
+#define AST_VIC_BASE                       0x1E6C0000	/* VIC */
+#define AST_SDMC_BASE                       0x1E6E0000	/* MMC */
+#define AST_UDC11_BASE                     0x1E6E1000	/* USB11 */
+#define AST_SCU_BASE                       0x1E6E2000	/* SCU */
+#define AST_CRYPTO_BASE                    0x1E6E3000	/* Crypto */
+
+#define AST_GRAPHIC_BASE                   0x1E6E6000	/* Graphics */
+
+#define AST_VIDEO_BASE                     0x1E700000	/* VIDEO ENGINE */
+#define AST_AHB_TO_PBUS_BASE               0x1E720000	/* APB -> PBUS */
+#define AST_MDMA_BASE                      0x1E740000	/* MDMA */
+#define AST_2D_BASE                        0x1E760000	/* 2D */
+#define AST_GPIO_BASE                      0x1E780000	/* GPIO */
+#define AST_RTC_BASE                       0x1E781000	/* RTC */
+#define AST_TIMER_BASE                     0x1E782000	/* TIMER #0~7*/
+#define AST_UART0_BASE                     0x1E783000	/* UART1 */
+#define AST_UART1_BASE                     0x1E784000	/* UART2 */
+#define AST_WDT_BASE                       0x1E785000	/* WDT */
+#define AST_PWM_BASE                       0x1E786000	/* PWM */
+#define AST_VUART0_BASE                    0x1E787000	/* VUART1 */
+#define AST_PUART_BASE                     0x1E788000	/* PUART */
+#define AST_LPC_BASE                       0x1E789000	/* LPC */
+#define AST_I2C_BASE                       0x1E78A000	/* I2C */
+#define AST_PECI_BASE                      0x1E78B000	/* PECI */
+#define AST_PCIARBITER_BASE                0x1E78C000	/* PCI ARBITER */
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast2200_irqs.h b/arch/arm/mach-aspeed/include/mach/ast2200_irqs.h
new file mode 100644
index 0000000..f0b880f
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast2200_irqs.h
@@ -0,0 +1,65 @@
+/*
+ *  arch/arm/plat-aspeed/include/plat/irqs.h
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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 _AST2200_IRQS_H_
+#define _AST2200_IRQS_H_                 1
+
+#define NR_IRQS                         (AST_VIC_NUM + ARCH_NR_GPIOS)
+//--------------GPIO ---------------------------------------------------------------
+#define ARCH_NR_GPIOS 					(GPIO_PORT_NUM*8)
+#define IRQ_GPIO_CHAIN_START			AST_VIC_NUM
+
+#define AST_VIC_NUM			32
+
+#define IRQ_SDRAM_ECC					0
+#define IRQ_MIC							1
+#define IRQ_MAC0						2			/* MAC 1 interrupt */
+#define IRQ_MAC1						3			/* MAC 2 interrupt */
+#define IRQ_CRYPTO						4
+#define IRQ_USB20_HUB					5
+#define IRQ_EHCI					5
+#define IRQ_XDMA						6
+#define IRQ_VIDEO						7
+#define IRQ_LPC							8
+#define IRQ_UART0						9			/* UART 1 interrupt */
+#define IRQ_UART1						10			/* UART 2 interrupt */
+//11 reserved 
+#define IRQ_I2C							12
+#define IRQ_UDC11					13
+//14 reserved 
+#define IRQ_PECI						15
+#define IRQ_TIMER0						16			/* TIMER 1 interrupt */
+#define IRQ_TIMER1						17			/* TIMER 2 interrupt */
+#define IRQ_TIMER2						18			/* TIMER 3 interrupt */
+#define IRQ_SMC							19
+#define IRQ_GPIO						20
+#define IRQ_SCU							21
+#define IRQ_RTC_SEC						22
+#define IRQ_RTC_DAY						23
+#define IRQ_RTC_HOUR					24
+#define IRQ_RTC_MIN						25
+#define IRQ_RTC							26
+#define IRQ_WDT							27
+#define IRQ_TACHO						28
+#define IRQ_2D							29
+#define IRQ_PCI							30
+#define IRQ_AHBC						31
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast2200_platform.h b/arch/arm/mach-aspeed/include/mach/ast2200_platform.h
new file mode 100644
index 0000000..324e15b
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast2200_platform.h
@@ -0,0 +1,55 @@
+/*
+ * 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 _AST2200_PLATFORM_H_
+#define _AST2200_PLATFORM_H_                 1
+
+#define AST_OLD_SMC_BASE						0x10000000		/*Legacy BMC Static Memory */
+#define AST_OLD_SMC_CTRL_BASE				0x16000000		/*Legacy BMC Static Memory Ctrl*/
+
+#define AST_AHB_CTRL_BASE            0x1E600000	/* AHB CONTROLLER */
+
+#define AST_MIC_BASE                       0x1E640000	/* MIC CONTROLLER */
+#define AST_MAC1_BASE                      0x1E660000	/* MAC1 */ 
+#define AST_MAC2_BASE                      0x1E680000	/* MAC2 */
+
+#define AST_USB20_BASE                     0x1E6A0000	/* USB 2.0 VIRTUAL HUB CONTROLLER */
+#define AST_VIC_BASE                       0x1E6C0000	/* VIC */
+#define AST_SDMC_BASE                       0x1E6E0000	/* MMC */
+#define AST_UDC11_BASE                     0x1E6E1000	/* USB11 */
+#define AST_SCU_BASE                       0x1E6E2000	/* SCU */
+#define AST_CRYPTO_BASE                    0x1E6E3000	/* Crypto */
+
+#define AST_GRAPHIC_BASE                   0x1E6E6000	/* Graphics */
+
+#define AST_VIDEO_BASE                     0x1E700000	/* VIDEO ENGINE */
+#define AST_AHB_TO_PBUS_BASE               0x1E720000	/* APB -> PBUS */
+#define AST_MDMA_BASE                      0x1E740000	/* MDMA */
+#define AST_2D_BASE                        0x1E760000	/* 2D */
+#define AST_GPIO_BASE                      0x1E780000	/* GPIO */
+#define AST_RTC_BASE                       0x1E781000	/* RTC */
+#define AST_TIMER_BASE                     0x1E782000	/* TIMER #0~7*/
+#define AST_UART0_BASE                     0x1E783000	/* UART1 */
+#define AST_UART1_BASE                     0x1E784000	/* UART2 */
+#define AST_WDT_BASE                       0x1E785000	/* WDT */
+#define AST_PWM_BASE                       0x1E786000	/* PWM */
+#define AST_VUART0_BASE                    0x1E787000	/* VUART1 */
+#define AST_PUART_BASE                     0x1E788000	/* PUART */
+#define AST_LPC_BASE                       0x1E789000	/* LPC */
+#define AST_I2C_BASE                       0x1E78A000	/* I2C */
+#define AST_PECI_BASE                      0x1E78B000	/* PECI */
+ 
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast2300_irqs.h b/arch/arm/mach-aspeed/include/mach/ast2300_irqs.h
new file mode 100644
index 0000000..2d7b0c8
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast2300_irqs.h
@@ -0,0 +1,92 @@
+/*
+ *  arch/arm/plat-aspeed/include/plat/irqs.h
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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 _AST2300_IRQS_H_
+#define _AST2300_IRQS_H_                 1
+
+#if defined(CONFIG_ARCH_AST1070)
+//----------VIC + GPIO + CVIC chain--------------------------------------------------
+#define NR_IRQS                         (AST_VIC_NUM + ARCH_NR_GPIOS + AST_CVIC_NUM)
+//--------------GPIO ---------------------------------------------------------------
+#define ARCH_NR_GPIOS 					(GPIO_PORT_NUM*8)
+#define IRQ_GPIO_CHAIN_START			(AST_VIC_NUM)
+//---------------CVIC---------------------------------------------------------------
+#define IRQ_C0_VIC_CHAIN					IRQ_GPIOL1
+#define IRQ_C0_VIC_CHAIN_START			(AST_VIC_NUM + ARCH_NR_GPIOS)
+//------------------- ---------------------------------------------------------------
+#else
+#define NR_IRQS                         (AST_VIC_NUM + ARCH_NR_GPIOS)
+//--------------GPIO ---------------------------------------------------------------
+#define ARCH_NR_GPIOS 					(GPIO_PORT_NUM*8)
+#define IRQ_GPIO_CHAIN_START			AST_VIC_NUM
+
+#endif
+
+
+#define AST_VIC_NUM			46
+
+#define IRQ_SDRAM_ECC					0
+#define IRQ_MIC							1
+#define IRQ_MAC0						2			/* MAC 1 interrupt */
+#define IRQ_MAC1						3			/* MAC 2 interrupt */
+#define IRQ_CRYPTO						4
+#define IRQ_USB20_HUB					5
+#define IRQ_EHCI					5
+#define IRQ_XDMA						6
+#define IRQ_VIDEO						7
+#define IRQ_LPC							8
+#define IRQ_UART1						9			/* UART 1 interrupt */
+#define IRQ_UART0						10			/* UART 5 interrupt */
+//11 Reserved
+#define IRQ_I2C							12
+#define IRQ_UDC11					13
+#define IRQ_UHCI					14
+#define IRQ_PECI						15
+#define IRQ_TIMER0						16			/* TIMER 1 interrupt */
+#define IRQ_TIMER1						17			/* TIMER 2 interrupt */
+#define IRQ_TIMER2						18			/* TIMER 3 interrupt */
+#define IRQ_SMC							19
+#define IRQ_GPIO						20
+#define IRQ_SCU							21
+#define IRQ_RTC							22
+//23 , 24 reserverd 
+#define IRQ_CRT							25
+#define IRQ_SDHC						26
+#define IRQ_WDT							27
+#define IRQ_TACHO						28
+#define IRQ_2D							29
+#define IRQ_SYS_WAKEUP					30
+#define IRQ_ADC							31
+#define IRQ_UART2						32			/* UART 2 interrupt */
+#define IRQ_UART3						33			/* UART 3 interrupt */
+#define IRQ_UART4						34			/* UART 4 interrupt */
+#define IRQ_TIMER3						35			/* TIMER 4 interrupt */
+#define IRQ_TIMER4						36
+#define IRQ_TIMER5						37
+#define IRQ_TIMER6						38
+#define IRQ_TIMER7						39			/* TIMER 8 interrupt */
+#define IRQ_SGPIO_MASTER				40
+#define IRQ_SGPIO_SLAVE					41
+#define IRQ_MCTP						42
+#define IRQ_JTAG						43
+//#define IRQ_RESERVED					44
+#define IRQ_CPU1						45
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast2300_platform.h b/arch/arm/mach-aspeed/include/mach/ast2300_platform.h
new file mode 100644
index 0000000..4898856
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast2300_platform.h
@@ -0,0 +1,72 @@
+/*
+ * 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 _AST2300_PLATFORM_H_
+#define _AST2300_PLATFORM_H_                 1
+
+#define AST_DRAM_BASE					0x40000000
+#define AST_SRAM_SIZE					(SZ_16K)
+
+#define AST_OLD_SMC_BASE						0x10000000		/*Legacy BMC Static Memory */
+#define AST_OLD_SMC_CTRL_BASE				0x16000000		/*Legacy BMC Static Memory Ctrl*/
+
+#define AST_AHB_CTRL_BASE            0x1E600000	/* AHB CONTROLLER */
+
+#define AST_FMC_BASE        					0x1E620000	/* NEW SMC CONTROLLER */
+#define AST_SPI_BASE        					0x1E630000	/* SPI CONTROLLER */
+#define AST_MIC_BASE                       0x1E640000	/* MIC CONTROLLER */
+#define AST_MAC0_BASE                      0x1E660000	/* MAC1 */ 
+#define AST_MAC1_BASE                      0x1E680000	/* MAC2 */
+
+#define AST_USB20_BASE                     0x1E6A0000	/* USB 2.0 VIRTUAL HUB CONTROLLER */
+#define AST_UHCI_BASE                0x1E6B0000	/* USB 1.1 HOST CONTROLLER */
+#define AST_VIC_BASE                       0x1E6C0000	/* VIC */
+#define AST_SDMC_BASE                       0x1E6E0000	/* SDRAM CTRL */
+#define AST_UDC11_BASE                     0x1E6E1000	/* USB11 */
+#define AST_SCU_BASE                       0x1E6E2000	/* SCU */
+#define AST_CRYPTO_BASE                    0x1E6E3000	/* Crypto */
+#define AST_JTAG_BASE                      0x1E6E4000	/* JTAG */
+#define AST_GRAPHIC_BASE                   0x1E6E6000	/* Graphics */
+#define AST_XDMA_BASE                      0x1E6E7000	/* XDMA */
+#define AST_MCTP_BASE                      0x1E6E8000	/* MCTP */
+#define AST_ADC_BASE                       0x1E6E9000	/* ADC */
+
+#define AST_LPC_PLUS_BASE                  0x1E6EC000	/* LPC+ Controller */
+
+#define AST_VIDEO_BASE                     0x1E700000	/* VIDEO ENGINE */
+#define AST_SRAM_BASE                      0x1E720000	/* SRAM */
+#define AST_SDHC_BASE                      0x1E740000	/* SDHC */
+#define AST_2D_BASE                        0x1E760000	/* 2D */
+#define AST_GPIO_BASE                      0x1E780000	/* GPIO */
+#define AST_RTC_BASE                       0x1E781000	/* RTC */
+#define AST_TIMER_BASE                     0x1E782000	/* TIMER #0~7*/
+#define AST_UART1_BASE                     0x1E783000	/* UART1 */
+#define AST_UART0_BASE                     0x1E784000	/* UART5 */
+#define AST_WDT_BASE                       0x1E785000	/* WDT */
+#define AST_PWM_BASE                       0x1E786000	/* PWM */
+#define AST_VUART0_BASE                    0x1E787000	/* VUART1 */
+#define AST_PUART_BASE                     0x1E788000	/* PUART */
+#define AST_LPC_BASE                       0x1E789000	/* LPC */
+#define AST_MBX_BASE                       0x1E789200	/* MailBox */
+#define AST_I2C_BASE                       0x1E78A000	/* I2C */
+#define AST_PECI_BASE                      0x1E78B000	/* PECI */
+#define AST_UART2_BASE                     0x1E78D000	/* UART2 */
+#define AST_UART3_BASE                     0x1E78E000	/* UART3 */
+#define AST_UART4_BASE                     0x1E78F000	/* UART4 */
+
+#define AST_LPC_BRIDGE						0x60000000
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast2400_irqs.h b/arch/arm/mach-aspeed/include/mach/ast2400_irqs.h
new file mode 100644
index 0000000..17c59da
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast2400_irqs.h
@@ -0,0 +1,96 @@
+/*
+ *  arch/arm/plat-aspeed/include/plat/irqs.h
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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 _AST2400_IRQS_H_
+#define _AST2400_IRQS_H_                 1
+
+#if defined(CONFIG_ARCH_AST1070)
+#include <mach/ast1070_irqs.h>
+#define MAX_AST1070_NR 2
+//----------VIC + CVIC + GPIO chain--------------------------------------------------
+#define NR_IRQS                         (AST_VIC_NUM + (AST_CVIC_NUM * MAX_AST1070_NR) + ARCH_NR_GPIOS)
+//--------------GPIO ---------------------------------------------------------------
+#define ARCH_NR_GPIOS 					(GPIO_PORT_NUM*8)
+#define IRQ_GPIO_CHAIN_START			(AST_VIC_NUM + (AST_CVIC_NUM * MAX_AST1070_NR))
+//------------------- ---------------------------------------------------------------
+#else
+//--------------GPIO ---------------------------------------------------------------
+#define ARCH_NR_GPIOS 					(GPIO_PORT_NUM*8)
+#define IRQ_GPIO_CHAIN_START			(AST_VIC_NUM)
+//------------------- ---------------------------------------------------------------
+#define NR_IRQS                         (AST_VIC_NUM + ARCH_NR_GPIOS)
+
+#endif
+
+#define AST_VIC_NUM			51
+
+#define IRQ_SDRAM_ECC					0
+#define IRQ_MIC							1
+#define IRQ_MAC0						2			/* MAC 1 interrupt */
+#define IRQ_MAC1						3			/* MAC 2 interrupt */
+#define IRQ_CRYPTO						4
+#define IRQ_USB20_HUB					5
+#define IRQ_EHCI					5
+#define IRQ_XDMA						6
+#define IRQ_VIDEO						7
+#define IRQ_LPC							8
+#define IRQ_UART1						9			/* UART 1 interrupt */
+#define IRQ_UART0						10			/* UART 5 interrupt */
+//11 Reserved
+#define IRQ_I2C							12
+#define IRQ_UDC11					13
+#define IRQ_UHCI					14
+#define IRQ_PECI						15
+#define IRQ_TIMER0						16			/* TIMER 1 interrupt */
+#define IRQ_TIMER1						17			/* TIMER 2 interrupt */
+#define IRQ_TIMER2						18			/* TIMER 3 interrupt */
+#define IRQ_SMC							19
+#define IRQ_GPIO						20
+#define IRQ_SCU							21
+#define IRQ_RTC							22
+//23 , 24 reserverd 
+#define IRQ_CRT							25
+#define IRQ_SDHC						26
+#define IRQ_WDT							27
+#define IRQ_TACHO						28
+#define IRQ_2D							29
+#define IRQ_SYS_WAKEUP					30
+#define IRQ_ADC							31
+#define IRQ_UART2						32			/* UART 2 interrupt */
+#define IRQ_UART3						33			/* UART 3 interrupt */
+#define IRQ_UART4						34			/* UART 4 interrupt */
+#define IRQ_TIMER3						35			/* TIMER 4 interrupt */
+#define IRQ_TIMER4						36
+#define IRQ_TIMER5						37
+#define IRQ_TIMER6						38
+#define IRQ_TIMER7						39			/* TIMER 8 interrupt */
+#define IRQ_SGPIO_MASTER				40
+#define IRQ_SGPIO_SLAVE					41
+#define IRQ_MCTP						42
+#define IRQ_JTAG						43
+//#define IRQ_RESERVED					44
+#define IRQ_CPU1						45
+#define IRQ_MAILBOX						46
+#define IRQ_EXT0						47
+#define IRQ_EXT1						48
+#define IRQ_EXT2						49
+#define IRQ_EXT3						50
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast2400_platform.h b/arch/arm/mach-aspeed/include/mach/ast2400_platform.h
new file mode 100644
index 0000000..e507953
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast2400_platform.h
@@ -0,0 +1,79 @@
+/*
+ * 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 _AST2400_PLATFORM_H_
+#define _AST2400_PLATFORM_H_                 1
+
+#define AST_DRAM_BASE					0x40000000
+
+#define AST_SRAM_SIZE					(SZ_16K*2)
+
+#define AST_OLD_SMC_BASE					0x10000000		/*Legacy BMC Static Memory */
+#define AST_OLD_SMC_CTRL_BASE				0x16000000		/*Legacy BMC Static Memory Ctrl*/
+
+#define AST_AHB_CTRL_BASE            0x1E600000	/* AHB CONTROLLER */
+
+#define AST_FMC_BASE        					0x1E620000	/* NEW SMC CONTROLLER */
+#define AST_SPI_BASE        					0x1E630000	/* SPI CONTROLLER */
+#define AST_MIC_BASE                       0x1E640000	/* MIC CONTROLLER */
+#define AST_MAC0_BASE                      0x1E660000	/* MAC1 */ 
+#define AST_MAC1_BASE                      0x1E680000	/* MAC2 */
+
+#define AST_USB20_BASE                     0x1E6A0000	/* USB 2.0 VIRTUAL HUB CONTROLLER */
+#define AST_EHCI_BASE                0x1E6A1000	/* USB 2.0 HOST CONTROLLER */
+#define AST_UHCI_BASE                0x1E6B0000	/* USB 1.1 HOST CONTROLLER */
+#define AST_VIC_BASE                       0x1E6C0000	/* VIC */
+#define AST_SDMC_BASE                       0x1E6E0000	/* SDRAM CTRL */
+#define AST_UDC11_BASE                     0x1E6E1000	/* USB11 */
+#define AST_SCU_BASE                       0x1E6E2000	/* SCU */
+#define AST_CRYPTO_BASE                    0x1E6E3000	/* Crypto */
+#define AST_JTAG_BASE                      0x1E6E4000	/* JTAG */
+#define AST_GRAPHIC_BASE                   0x1E6E6000	/* Graphics */
+#define AST_XDMA_BASE                      0x1E6E7000	/* XDMA */
+#define AST_MCTP_BASE                      0x1E6E8000	/* MCTP */
+#define AST_ADC_BASE                       0x1E6E9000	/* ADC */
+
+#define AST_LPC_PLUS_BASE                  0x1E6EC000	/* LPC+ Controller */
+
+#define AST_VIDEO_BASE                     0x1E700000	/* VIDEO ENGINE */
+#define AST_SRAM_BASE                      0x1E720000	/* SRAM */
+#define AST_SDHC_BASE                      0x1E740000	/* SDHC */
+#define AST_2D_BASE                        0x1E760000	/* 2D */
+#define AST_GPIO_BASE                      0x1E780000	/* GPIO */
+#define AST_RTC_BASE                       0x1E781000	/* RTC */
+#define AST_TIMER_BASE                     0x1E782000	/* TIMER #0~7*/
+#define AST_UART1_BASE                     0x1E783000	/* UART1 */
+#define AST_UART0_BASE                     0x1E784000	/* UART5 */
+#define AST_WDT_BASE                       0x1E785000	/* WDT */
+#define AST_PWM_BASE                       0x1E786000	/* PWM */
+#define AST_VUART0_BASE                    0x1E787000	/* VUART1 */
+#define AST_PUART_BASE                     0x1E788000	/* PUART */
+#define AST_LPC_BASE                       0x1E789000	/* LPC */
+#define AST_MBX_BASE                       0x1E789200	/* MailBox */
+#define AST_I2C_BASE                       0x1E78A000	/* I2C */
+#define AST_PECI_BASE                      0x1E78B000	/* PECI */
+#define AST_PCIARBITER_BASE                0x1E78C000	/* PCI ARBITER */
+#define AST_UART2_BASE                     0x1E78D000	/* UART2 */
+#define AST_UART3_BASE                     0x1E78E000	/* UART3 */
+#define AST_UART4_BASE                     0x1E78F000	/* UART4 */
+#define AST_SPI0_MEM					0x30000000
+
+#define AST_LPC_PLUS_BRIDGE						0x70000000
+
+#define AST_LPC_BRIDGE						0x60000000
+
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast_gpio_irqs.h b/arch/arm/mach-aspeed/include/mach/ast_gpio_irqs.h
new file mode 100644
index 0000000..3bae742
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast_gpio_irqs.h
@@ -0,0 +1,272 @@
+/*
+ *  file : gpio_irqs.h
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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 _GPIO_IRQS_H_
+#define _GPIO_IRQS_H_                 1
+
+#if defined(CONFIG_ARCH_AST1010)
+#define GPIO_PORT_NUM		19
+#elif defined(CONFIG_ARCH_AST2000)
+#define GPIO_PORT_NUM		19
+#elif defined(CONFIG_ARCH_AST2100) 
+#define GPIO_PORT_NUM		19
+#elif defined(CONFIG_ARCH_AST2200) 
+#define GPIO_PORT_NUM		19
+#elif defined(CONFIG_ARCH_AST2300)
+#define GPIO_PORT_NUM		19
+#elif defined(CONFIG_ARCH_AST2400)
+#define GPIO_PORT_NUM		28
+#elif defined(CONFIG_ARCH_AST1520)
+#define GPIO_PORT_NUM		28
+#else
+#err "no define for gpio irqs.h"
+#endif
+
+
+#define IRQ_GPIOA0						(IRQ_GPIO_CHAIN_START + 0)
+#define IRQ_GPIOA1						(IRQ_GPIO_CHAIN_START + 1)
+#define IRQ_GPIOA2						(IRQ_GPIO_CHAIN_START + 2)
+#define IRQ_GPIOA3						(IRQ_GPIO_CHAIN_START + 3)
+#define IRQ_GPIOA4						(IRQ_GPIO_CHAIN_START + 4)
+#define IRQ_GPIOA5						(IRQ_GPIO_CHAIN_START + 5)
+#define IRQ_GPIOA6						(IRQ_GPIO_CHAIN_START + 6)
+#define IRQ_GPIOA7						(IRQ_GPIO_CHAIN_START + 7)
+#define IRQ_GPIOB0						(IRQ_GPIO_CHAIN_START + 8)
+#define IRQ_GPIOB1						(IRQ_GPIO_CHAIN_START + 9)
+#define IRQ_GPIOB2						(IRQ_GPIO_CHAIN_START + 10)
+#define IRQ_GPIOB3						(IRQ_GPIO_CHAIN_START + 11)
+#define IRQ_GPIOB4						(IRQ_GPIO_CHAIN_START + 12)
+#define IRQ_GPIOB5						(IRQ_GPIO_CHAIN_START + 13)
+#define IRQ_GPIOB6						(IRQ_GPIO_CHAIN_START + 14)
+#define IRQ_GPIOB7						(IRQ_GPIO_CHAIN_START + 15)
+#define IRQ_GPIOC0						(IRQ_GPIO_CHAIN_START + 16)
+#define IRQ_GPIOC1						(IRQ_GPIO_CHAIN_START + 17)
+#define IRQ_GPIOC2						(IRQ_GPIO_CHAIN_START + 18)
+#define IRQ_GPIOC3						(IRQ_GPIO_CHAIN_START + 19)
+#define IRQ_GPIOC4						(IRQ_GPIO_CHAIN_START + 20)
+#define IRQ_GPIOC5						(IRQ_GPIO_CHAIN_START + 21)
+#define IRQ_GPIOC6						(IRQ_GPIO_CHAIN_START + 22)
+#define IRQ_GPIOC7						(IRQ_GPIO_CHAIN_START + 23)
+#define IRQ_GPIOD0						(IRQ_GPIO_CHAIN_START + 24)
+#define IRQ_GPIOD1						(IRQ_GPIO_CHAIN_START + 25)
+#define IRQ_GPIOD2						(IRQ_GPIO_CHAIN_START + 26)
+#define IRQ_GPIOD3						(IRQ_GPIO_CHAIN_START + 27)
+#define IRQ_GPIOD4						(IRQ_GPIO_CHAIN_START + 28)
+#define IRQ_GPIOD5						(IRQ_GPIO_CHAIN_START + 29)
+#define IRQ_GPIOD6						(IRQ_GPIO_CHAIN_START + 30)
+#define IRQ_GPIOD7						(IRQ_GPIO_CHAIN_START + 31)
+#define IRQ_GPIOE0						(IRQ_GPIO_CHAIN_START + 32)
+#define IRQ_GPIOE1						(IRQ_GPIO_CHAIN_START + 33)
+#define IRQ_GPIOE2						(IRQ_GPIO_CHAIN_START + 34)
+#define IRQ_GPIOE3						(IRQ_GPIO_CHAIN_START + 35)
+#define IRQ_GPIOE4						(IRQ_GPIO_CHAIN_START + 36)
+#define IRQ_GPIOE5						(IRQ_GPIO_CHAIN_START + 37)
+#define IRQ_GPIOE6						(IRQ_GPIO_CHAIN_START + 38)
+#define IRQ_GPIOE7						(IRQ_GPIO_CHAIN_START + 39)
+#define IRQ_GPIOF0						(IRQ_GPIO_CHAIN_START + 40)
+#define IRQ_GPIOF1						(IRQ_GPIO_CHAIN_START + 41)
+#define IRQ_GPIOF2						(IRQ_GPIO_CHAIN_START + 42)
+#define IRQ_GPIOF3						(IRQ_GPIO_CHAIN_START + 43)
+#define IRQ_GPIOF4						(IRQ_GPIO_CHAIN_START + 44)
+#define IRQ_GPIOF5						(IRQ_GPIO_CHAIN_START + 45)
+#define IRQ_GPIOF6						(IRQ_GPIO_CHAIN_START + 46)
+#define IRQ_GPIOF7						(IRQ_GPIO_CHAIN_START + 47)
+#define IRQ_GPIOG0						(IRQ_GPIO_CHAIN_START + 48)
+#define IRQ_GPIOG1						(IRQ_GPIO_CHAIN_START + 49)
+#define IRQ_GPIOG2						(IRQ_GPIO_CHAIN_START + 50)
+#define IRQ_GPIOG3						(IRQ_GPIO_CHAIN_START + 51)
+#define IRQ_GPIOG4						(IRQ_GPIO_CHAIN_START + 52)
+#define IRQ_GPIOG5						(IRQ_GPIO_CHAIN_START + 53)
+#define IRQ_GPIOG6						(IRQ_GPIO_CHAIN_START + 54)
+#define IRQ_GPIOG7						(IRQ_GPIO_CHAIN_START + 55)
+#define IRQ_GPIOH0						(IRQ_GPIO_CHAIN_START + 56)
+#define IRQ_GPIOH1						(IRQ_GPIO_CHAIN_START + 57)
+#define IRQ_GPIOH2						(IRQ_GPIO_CHAIN_START + 58)
+#define IRQ_GPIOH3						(IRQ_GPIO_CHAIN_START + 59)
+#define IRQ_GPIOH4						(IRQ_GPIO_CHAIN_START + 60)
+#define IRQ_GPIOH5						(IRQ_GPIO_CHAIN_START + 61)
+#define IRQ_GPIOH6						(IRQ_GPIO_CHAIN_START + 62)
+#define IRQ_GPIOH7						(IRQ_GPIO_CHAIN_START + 63)
+#define IRQ_GPIOI0						(IRQ_GPIO_CHAIN_START + 64)
+#define IRQ_GPIOI1						(IRQ_GPIO_CHAIN_START + 65)
+#define IRQ_GPIOI2						(IRQ_GPIO_CHAIN_START + 66)
+#define IRQ_GPIOI3						(IRQ_GPIO_CHAIN_START + 67)
+#define IRQ_GPIOI4						(IRQ_GPIO_CHAIN_START + 68)
+#define IRQ_GPIOI5						(IRQ_GPIO_CHAIN_START + 69)
+#define IRQ_GPIOI6						(IRQ_GPIO_CHAIN_START + 70)
+#define IRQ_GPIOI7						(IRQ_GPIO_CHAIN_START + 71)
+#define IRQ_GPIOJ0						(IRQ_GPIO_CHAIN_START + 72)
+#define IRQ_GPIOJ1						(IRQ_GPIO_CHAIN_START + 73)
+#define IRQ_GPIOJ2						(IRQ_GPIO_CHAIN_START + 74)
+#define IRQ_GPIOJ3						(IRQ_GPIO_CHAIN_START + 75)
+#define IRQ_GPIOJ4						(IRQ_GPIO_CHAIN_START + 76)
+#define IRQ_GPIOJ5						(IRQ_GPIO_CHAIN_START + 77)
+#define IRQ_GPIOJ6						(IRQ_GPIO_CHAIN_START + 78)
+#define IRQ_GPIOJ7						(IRQ_GPIO_CHAIN_START + 79)
+#define IRQ_GPIOK0						(IRQ_GPIO_CHAIN_START + 80)
+#define IRQ_GPIOK1						(IRQ_GPIO_CHAIN_START + 81)
+#define IRQ_GPIOK2						(IRQ_GPIO_CHAIN_START + 82)
+#define IRQ_GPIOK3						(IRQ_GPIO_CHAIN_START + 83)
+#define IRQ_GPIOK4						(IRQ_GPIO_CHAIN_START + 84)
+#define IRQ_GPIOK5						(IRQ_GPIO_CHAIN_START + 85)
+#define IRQ_GPIOK6						(IRQ_GPIO_CHAIN_START + 86)
+#define IRQ_GPIOK7						(IRQ_GPIO_CHAIN_START + 87)
+#define IRQ_GPIOL0						(IRQ_GPIO_CHAIN_START + 88)
+#define IRQ_GPIOL1						(IRQ_GPIO_CHAIN_START + 89)
+#define IRQ_GPIOL2						(IRQ_GPIO_CHAIN_START + 90)
+#define IRQ_GPIOL3						(IRQ_GPIO_CHAIN_START + 91)
+#define IRQ_GPIOL4						(IRQ_GPIO_CHAIN_START + 92)
+#define IRQ_GPIOL5						(IRQ_GPIO_CHAIN_START + 93)
+#define IRQ_GPIOL6						(IRQ_GPIO_CHAIN_START + 94)
+#define IRQ_GPIOL7						(IRQ_GPIO_CHAIN_START + 95)
+#define IRQ_GPIOM0						(IRQ_GPIO_CHAIN_START + 96)
+#define IRQ_GPIOM1						(IRQ_GPIO_CHAIN_START + 97)
+#define IRQ_GPIOM2						(IRQ_GPIO_CHAIN_START + 98)
+#define IRQ_GPIOM3						(IRQ_GPIO_CHAIN_START + 99)
+#define IRQ_GPIOM4						(IRQ_GPIO_CHAIN_START + 100)
+#define IRQ_GPIOM5						(IRQ_GPIO_CHAIN_START + 101)
+#define IRQ_GPIOM6						(IRQ_GPIO_CHAIN_START + 102)
+#define IRQ_GPIOM7						(IRQ_GPIO_CHAIN_START + 103)
+#define IRQ_GPION0						(IRQ_GPIO_CHAIN_START + 104)
+#define IRQ_GPION1						(IRQ_GPIO_CHAIN_START + 105)
+#define IRQ_GPION2						(IRQ_GPIO_CHAIN_START + 106)
+#define IRQ_GPION3						(IRQ_GPIO_CHAIN_START + 107)
+#define IRQ_GPION4						(IRQ_GPIO_CHAIN_START + 108)
+#define IRQ_GPION5						(IRQ_GPIO_CHAIN_START + 109)
+#define IRQ_GPION6						(IRQ_GPIO_CHAIN_START + 110)
+#define IRQ_GPION7						(IRQ_GPIO_CHAIN_START + 111)
+#define IRQ_GPIOO0						(IRQ_GPIO_CHAIN_START + 112)
+#define IRQ_GPIOO1						(IRQ_GPIO_CHAIN_START + 113)
+#define IRQ_GPIOO2						(IRQ_GPIO_CHAIN_START + 114)
+#define IRQ_GPIOO3						(IRQ_GPIO_CHAIN_START + 115)
+#define IRQ_GPIOO4						(IRQ_GPIO_CHAIN_START + 116)
+#define IRQ_GPIOO5						(IRQ_GPIO_CHAIN_START + 117)
+#define IRQ_GPIOO6						(IRQ_GPIO_CHAIN_START + 118)
+#define IRQ_GPIOO7						(IRQ_GPIO_CHAIN_START + 119)
+#define IRQ_GPIOP0						(IRQ_GPIO_CHAIN_START + 120)
+#define IRQ_GPIOP1						(IRQ_GPIO_CHAIN_START + 121)
+#define IRQ_GPIOP2						(IRQ_GPIO_CHAIN_START + 122)
+#define IRQ_GPIOP3						(IRQ_GPIO_CHAIN_START + 123)
+#define IRQ_GPIOP4						(IRQ_GPIO_CHAIN_START + 124)
+#define IRQ_GPIOP5						(IRQ_GPIO_CHAIN_START + 125)
+#define IRQ_GPIOP6						(IRQ_GPIO_CHAIN_START + 126)
+#define IRQ_GPIOP7						(IRQ_GPIO_CHAIN_START + 127)
+#define IRQ_GPIOQ0						(IRQ_GPIO_CHAIN_START + 128)
+#define IRQ_GPIOQ1						(IRQ_GPIO_CHAIN_START + 129)
+#define IRQ_GPIOQ2						(IRQ_GPIO_CHAIN_START + 130)
+#define IRQ_GPIOQ3						(IRQ_GPIO_CHAIN_START + 131)
+#define IRQ_GPIOQ4						(IRQ_GPIO_CHAIN_START + 132)
+#define IRQ_GPIOQ5						(IRQ_GPIO_CHAIN_START + 133)
+#define IRQ_GPIOQ6						(IRQ_GPIO_CHAIN_START + 134)
+#define IRQ_GPIOQ7						(IRQ_GPIO_CHAIN_START + 135)
+#define IRQ_GPIOR0						(IRQ_GPIO_CHAIN_START + 136)
+#define IRQ_GPIOR1						(IRQ_GPIO_CHAIN_START + 137)
+#define IRQ_GPIOR2						(IRQ_GPIO_CHAIN_START + 138)
+#define IRQ_GPIOR3						(IRQ_GPIO_CHAIN_START + 139)
+#define IRQ_GPIOR4						(IRQ_GPIO_CHAIN_START + 140)
+#define IRQ_GPIOR5						(IRQ_GPIO_CHAIN_START + 141)
+#define IRQ_GPIOR6						(IRQ_GPIO_CHAIN_START + 142)
+#define IRQ_GPIOR7						(IRQ_GPIO_CHAIN_START + 143)
+#define IRQ_GPIOS0						(IRQ_GPIO_CHAIN_START + 144)
+#define IRQ_GPIOS1						(IRQ_GPIO_CHAIN_START + 145)
+#define IRQ_GPIOS2						(IRQ_GPIO_CHAIN_START + 146)
+#define IRQ_GPIOS3						(IRQ_GPIO_CHAIN_START + 147)
+#define IRQ_GPIOS4						(IRQ_GPIO_CHAIN_START + 148)
+#define IRQ_GPIOS5						(IRQ_GPIO_CHAIN_START + 149)
+#define IRQ_GPIOS6						(IRQ_GPIO_CHAIN_START + 150)
+#define IRQ_GPIOS7						(IRQ_GPIO_CHAIN_START + 151)
+
+#if defined(CONFIG_ARCH_AST2400) || defined(CONFIG_ARCH_AST1520)
+
+#define IRQ_GPIOT0						(IRQ_GPIO_CHAIN_START + 152)
+#define IRQ_GPIOT1						(IRQ_GPIO_CHAIN_START + 153)
+#define IRQ_GPIOT2						(IRQ_GPIO_CHAIN_START + 154)
+#define IRQ_GPIOT3						(IRQ_GPIO_CHAIN_START + 155)
+#define IRQ_GPIOT4						(IRQ_GPIO_CHAIN_START + 156)
+#define IRQ_GPIOT5						(IRQ_GPIO_CHAIN_START + 157)
+#define IRQ_GPIOT6						(IRQ_GPIO_CHAIN_START + 158)
+#define IRQ_GPIOT7						(IRQ_GPIO_CHAIN_START + 159)
+#define IRQ_GPIOU0						(IRQ_GPIO_CHAIN_START + 161)
+#define IRQ_GPIOU1						(IRQ_GPIO_CHAIN_START + 162)
+#define IRQ_GPIOU2						(IRQ_GPIO_CHAIN_START + 163)
+#define IRQ_GPIOU3						(IRQ_GPIO_CHAIN_START + 164)
+#define IRQ_GPIOU4						(IRQ_GPIO_CHAIN_START + 165)
+#define IRQ_GPIOU5						(IRQ_GPIO_CHAIN_START + 166)
+#define IRQ_GPIOU6						(IRQ_GPIO_CHAIN_START + 167)
+#define IRQ_GPIOU7						(IRQ_GPIO_CHAIN_START + 168)
+#define IRQ_GPIOV0						(IRQ_GPIO_CHAIN_START + 169)
+#define IRQ_GPIOV1						(IRQ_GPIO_CHAIN_START + 170)
+#define IRQ_GPIOV2						(IRQ_GPIO_CHAIN_START + 171)
+#define IRQ_GPIOV3						(IRQ_GPIO_CHAIN_START + 172)
+#define IRQ_GPIOV4						(IRQ_GPIO_CHAIN_START + 173)
+#define IRQ_GPIOV5						(IRQ_GPIO_CHAIN_START + 174)
+#define IRQ_GPIOV6						(IRQ_GPIO_CHAIN_START + 175)
+#define IRQ_GPIOV7						(IRQ_GPIO_CHAIN_START + 176)
+#define IRQ_GPIOW0						(IRQ_GPIO_CHAIN_START + 177)
+#define IRQ_GPIOW1						(IRQ_GPIO_CHAIN_START + 178)
+#define IRQ_GPIOW2						(IRQ_GPIO_CHAIN_START + 179)
+#define IRQ_GPIOW3						(IRQ_GPIO_CHAIN_START + 181)
+#define IRQ_GPIOW4						(IRQ_GPIO_CHAIN_START + 182)
+#define IRQ_GPIOW5						(IRQ_GPIO_CHAIN_START + 183)
+#define IRQ_GPIOW6						(IRQ_GPIO_CHAIN_START + 184)
+#define IRQ_GPIOW7						(IRQ_GPIO_CHAIN_START + 185)
+#define IRQ_GPIOX0						(IRQ_GPIO_CHAIN_START + 186)
+#define IRQ_GPIOX1						(IRQ_GPIO_CHAIN_START + 187)
+#define IRQ_GPIOX2						(IRQ_GPIO_CHAIN_START + 188)
+#define IRQ_GPIOX3						(IRQ_GPIO_CHAIN_START + 189)
+#define IRQ_GPIOX4						(IRQ_GPIO_CHAIN_START + 190)
+#define IRQ_GPIOX5						(IRQ_GPIO_CHAIN_START + 191)
+#define IRQ_GPIOX6						(IRQ_GPIO_CHAIN_START + 192)
+#define IRQ_GPIOX7						(IRQ_GPIO_CHAIN_START + 193)
+#define IRQ_GPIOY0						(IRQ_GPIO_CHAIN_START + 194)
+#define IRQ_GPIOY1						(IRQ_GPIO_CHAIN_START + 195)
+#define IRQ_GPIOY2						(IRQ_GPIO_CHAIN_START + 196)
+#define IRQ_GPIOY3						(IRQ_GPIO_CHAIN_START + 197)
+#define IRQ_GPIOY4						(IRQ_GPIO_CHAIN_START + 198)
+#define IRQ_GPIOY5						(IRQ_GPIO_CHAIN_START + 199)
+#define IRQ_GPIOY6						(IRQ_GPIO_CHAIN_START + 200)
+#define IRQ_GPIOY7						(IRQ_GPIO_CHAIN_START + 201)
+#define IRQ_GPIOZ0						(IRQ_GPIO_CHAIN_START + 202)
+#define IRQ_GPIOZ1						(IRQ_GPIO_CHAIN_START + 203)
+#define IRQ_GPIOZ2						(IRQ_GPIO_CHAIN_START + 204)
+#define IRQ_GPIOZ3						(IRQ_GPIO_CHAIN_START + 205)
+#define IRQ_GPIOZ4						(IRQ_GPIO_CHAIN_START + 206)
+#define IRQ_GPIOZ5						(IRQ_GPIO_CHAIN_START + 207)
+#define IRQ_GPIOZ6						(IRQ_GPIO_CHAIN_START + 208)
+#define IRQ_GPIOZ7						(IRQ_GPIO_CHAIN_START + 209)
+#define IRQ_GPIOAA0						(IRQ_GPIO_CHAIN_START + 210)
+#define IRQ_GPIOAA1						(IRQ_GPIO_CHAIN_START + 211)
+#define IRQ_GPIOAA2						(IRQ_GPIO_CHAIN_START + 212)
+#define IRQ_GPIOAA3						(IRQ_GPIO_CHAIN_START + 213)
+#define IRQ_GPIOAA4						(IRQ_GPIO_CHAIN_START + 214)
+#define IRQ_GPIOAA5						(IRQ_GPIO_CHAIN_START + 215)
+#define IRQ_GPIOAA6						(IRQ_GPIO_CHAIN_START + 216)
+#define IRQ_GPIOAA7						(IRQ_GPIO_CHAIN_START + 217)
+#define IRQ_GPIOBB0						(IRQ_GPIO_CHAIN_START + 218)
+#define IRQ_GPIOBB1						(IRQ_GPIO_CHAIN_START + 219)
+#define IRQ_GPIOBB2						(IRQ_GPIO_CHAIN_START + 220)
+#define IRQ_GPIOBB3						(IRQ_GPIO_CHAIN_START + 221)
+#define IRQ_GPIOBB4						(IRQ_GPIO_CHAIN_START + 222)
+#define IRQ_GPIOBB5						(IRQ_GPIO_CHAIN_START + 223)
+#define IRQ_GPIOBB6						(IRQ_GPIO_CHAIN_START + 224)
+#define IRQ_GPIOBB7						(IRQ_GPIO_CHAIN_START + 225)
+#endif
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast_lcd.h b/arch/arm/mach-aspeed/include/mach/ast_lcd.h
new file mode 100755
index 0000000..20963eb
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast_lcd.h
@@ -0,0 +1,61 @@
+ /********************************************************************************
+* File Name     : drivers/video/ast_lcd.h
+* Author         : Ryan Chen
+* Description   : ASPEED LCD Panel Timing 
+*
+* Copyright (C) ASPEED Tech. 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
+
+*   History      :
+*    1. 2012/12/27 Ryan Chen create this file
+*        
+*
+********************************************************************************/
+#include <linux/fb.h>
+
+//# Define IO __ for control 
+#define YUV_MODE 0x4630
+#define CHANGE_YUV_ADDR 0x4631
+#define CHANGE_ADDR 0x4632
+#define OVERSCAN 0x4634
+
+
+enum astfb_color_format {
+	ASTFB_COLOR_RGB565 = 0,
+	ASTFB_COLOR_RGB888,
+	ASTFB_COLOR_YUV444,
+	ASTFB_COLOR_YUV420,
+};
+
+struct aspeed_lcd_panel {
+	struct fb_videomode	mode;
+	signed short		width;	/* width in mm */
+	signed short		height;	/* height in mm */
+};
+
+struct ast_monitor_info {
+	int status; //0: no data   1:get data
+	int type;   //0:dvi  1:hdmi
+	struct fb_monspecs specs;
+	char edid[256];
+};
+
+struct ast_fb_plat_data {
+	u32 (*get_clk)(void);
+};
+
+int ast_vga_get_info(struct fb_info *fb_info);
+int ast_hdmi_get_info(struct fb_info *fb_info);
+void ast_hdmi_enable(int en);
+int vga_read_edid(void);
+
diff --git a/arch/arm/mach-aspeed/include/mach/ast_lpc_irqs.h b/arch/arm/mach-aspeed/include/mach/ast_lpc_irqs.h
new file mode 100644
index 0000000..bbb3878
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast_lpc_irqs.h
@@ -0,0 +1,34 @@
+/*
+ *  arch/arm/plat-aspeed/include/plat/gpio_irqs.h
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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 _LPC_IRQS_H_
+#define _LPC_IRQS_H_                 1
+
+#define AST_LPC_IRQ_NUM 		7
+
+#define IRQ_KCS0						(IRQ_LPC_CHAIN_START + 0)
+#define IRQ_KCS1						(IRQ_LPC_CHAIN_START + 1)
+#define IRQ_KCS2						(IRQ_LPC_CHAIN_START + 2)
+#define IRQ_KCS3						(IRQ_LPC_CHAIN_START + 3)
+#define IRQ_KCS4						(IRQ_LPC_CHAIN_START + 4)
+#define IRQ_SNOOP0						(IRQ_LPC_CHAIN_START + 5)
+#define IRQ_SNOOP1						(IRQ_LPC_CHAIN_START + 6)
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/ast_pwm_techo.h b/arch/arm/mach-aspeed/include/mach/ast_pwm_techo.h
new file mode 100644
index 0000000..51d4ae3
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast_pwm_techo.h
@@ -0,0 +1,13 @@
+/*
+ *  ast_pwm_techo_h  
+ *
+ *
+ * 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.
+ */
+struct ast_pwm_driver_data {
+	u32 (*get_pwm_clock)(void);
+};
+
diff --git a/arch/arm/mach-aspeed/include/mach/ast_spi.h b/arch/arm/mach-aspeed/include/mach/ast_spi.h
new file mode 100755
index 0000000..d612967
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast_spi.h
@@ -0,0 +1,14 @@
+/*
+ *  ast_spi_h  
+ *
+ *
+ * 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.
+ */
+
+struct ast_spi_driver_data {
+		u32 	(*get_div)(u32 max_speed_hz);
+		u16		num_chipselect;
+};
diff --git a/arch/arm/mach-aspeed/include/mach/ast_video.h b/arch/arm/mach-aspeed/include/mach/ast_video.h
new file mode 100644
index 0000000..18f9189
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast_video.h
@@ -0,0 +1,89 @@
+ /********************************************************************************
+* File Name     : drivers/video/ast_video.h
+* Author         : Ryan Chen
+* Description   : ASPEED Video Engine
+*
+* Copyright (C) ASPEED Tech. 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
+
+*   History      :
+*    1. 2012/12/27 Ryan Chen create this file
+*        
+*
+********************************************************************************/
+typedef enum ast_video_mode {
+	VIDEO_SINGLE_MODE = 0,
+	VIDEO_FRAME_MODE,
+	VIDEO_STREAM_MODE,
+} video_mode;
+
+//VR08[2]
+typedef enum ast_video_source {
+	VIDEO_SOURCE_UNKNOW = 0,	//maybe memory .. TODO ...
+	VIDEO_SOURCE_INTERNAL,
+	VIDEO_SOURCE_EXTERNAL,
+} video_source;
+
+//VR08[5]
+typedef enum ast_vga_mode {
+	VIDEO_VGA_DIRECT_MODE = 0,
+	VIDEO_VGA_CAPTURE_MODE,
+} vga_mode;
+
+//VR08[4]
+typedef enum ast_video_dis_en {
+	VIDEO_EXT_DE_SIGNAL = 0,
+	VIDEO_INT_DE_SIGNAL,
+} display_enable;
+
+typedef enum video_compress_format {
+	VIDEO_YUV444 = 0,
+	VIDEO_YUV420,
+} compress_formate;
+
+typedef enum video_color_format {
+	VIDEO_COLOR_RGB565 = 0,
+	VIDEO_COLOR_RGB888,
+	VIDEO_COLOR_YUV444,
+	VIDEO_COLOR_YUV420,
+} color_formate;
+
+typedef enum vga_color_mode {
+	VGA_NO_SIGNAL = 0,
+	EGA_MODE,
+	VGA_MODE,
+	VGA_15BPP_MODE,
+	VGA_16BPP_MODE,
+	VGA_32BPP_MODE,
+} color_mode;
+
+typedef enum video_stage {
+	NONE,
+	POLARITY,
+	RESOLUTION,
+	INIT,
+	RUN,
+} stage;
+
+struct ast_video_plat_data {
+	u32 (*get_clk)(void);
+	void (*ctrl_reset)(void);
+	void (*vga_display)(u8 enable);
+	u32 (*get_vga_base)(void);
+	video_source	input_source;	
+	video_mode	mode;
+	u8	rc4_enable;
+	u8	scaling;
+	compress_formate compress;
+};
+
diff --git a/arch/arm/mach-aspeed/include/mach/ast_wdt.h b/arch/arm/mach-aspeed/include/mach/ast_wdt.h
new file mode 100755
index 0000000..6d7d7f47
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ast_wdt.h
@@ -0,0 +1,11 @@
+/*
+ *  ast_wdt_h  
+ *
+ *
+ * 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.
+ */
+
+ extern void ast_soc_wdt_reset(void);
diff --git a/arch/arm/mach-aspeed/include/mach/debug-macro.S b/arch/arm/mach-aspeed/include/mach/debug-macro.S
new file mode 100644
index 0000000..0b7c927
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/debug-macro.S
@@ -0,0 +1,22 @@
+/* debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * 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 <mach/platform.h>
+#include <mach/hardware.h>
+	
+	.macro	addruart, rx, tmp
+	mrc 	p15, 0, \rx, c1, c0
+	tst 	\rx, #1 								@ MMU enabled?
+	ldreq	\rx, =AST_UART0_BASE
+	ldrne	\rx, =IO_ADDRESS(AST_UART0_BASE)
+	orr 	\rx, \rx, #0x00012000
+	.endm
+	
+#define UART_SHIFT      2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-aspeed/include/mach/dma.h b/arch/arm/mach-aspeed/include/mach/dma.h
new file mode 100644
index 0000000..36c141d
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/dma.h
@@ -0,0 +1,25 @@
+/*
+ *  dma.h
+ *
+ * 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
+
+#define MAX_DMA_ADDRESS		0xffffffff
+
+#define MAX_DMA_CHANNELS	0
+
+#endif /* _ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-aspeed/include/mach/entry-macro.S b/arch/arm/mach-aspeed/include/mach/entry-macro.S
new file mode 100644
index 0000000..88b4417
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/entry-macro.S
@@ -0,0 +1,191 @@
+/*
+ * entry-macro.S
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/regs-intr.h>
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_preamble, base, tmp
+		ldr	\base, =IO_ADDRESS(AST_VIC_BASE)
+		.endm
+
+		.macro	arch_ret_to_user, tmp1, tmp2
+		.endm
+#if 1
+
+#if defined(NEW_VIC)
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		
+		ldr	\tmp, =IO_ADDRESS(AST_SCU_BASE)
+		ldr	\irqnr, [\tmp, #0x44]
+
+		cmp	\irqnr, #0
+		beq	2000f
+		
+1000:           /* pass1 */
+                cmp	\irqnr, #32
+                ble	1001f
+		ldr	\tmp, =IO_ADDRESS(AST_VIC_BASE)
+		ldr	\irqstat, [\tmp, #0x84]
+                sub	\irqnr, \irqnr, #32		
+		mov	\tmp, #32
+		sub	\tmp, \tmp, \irqnr
+                mov     \irqstat, \irqstat, lsl \tmp	/* mask uncompare parts */
+                mov     \irqstat, \irqstat, lsr \tmp
+                mov	\irqnr, #63
+                clz     \tmp, \irqstat
+                cmp     \tmp, #32
+                bne     3000f  
+                mov	\irqnr, #32                
+1001:
+		ldr	\tmp, =IO_ADDRESS(AST_VIC_BASE)
+		ldr	\irqstat, [\tmp, #0x00]
+		mov	\tmp, #32
+		sub	\tmp, \tmp, \irqnr		
+                mov     \irqstat, \irqstat, lsl \tmp	/* mask uncompare parts */
+                mov     \irqstat, \irqstat, lsr \tmp
+                mov	\irqnr, #31                
+                clz     \tmp, \irqstat
+                cmp     \tmp, #32
+                bne	3000f
+                
+2000:           /* pass 2 */
+		ldr	\tmp, =IO_ADDRESS(AST_VIC_BASE)
+		ldr	\irqstat, [\tmp, #0x84]
+                mov	\irqnr, #63
+                clz     \tmp, \irqstat
+                cmp     \tmp, #32
+                bne     3000f  
+2001:                
+		ldr	\tmp, =IO_ADDRESS(AST_VIC_BASE)
+		ldr	\irqstat, [\tmp, #0x00]
+                mov	\irqnr, #31		
+                clz     \tmp, \irqstat
+                cmp     \tmp, #32
+                beq     4000f			/* not find */  
+                                
+3000:		/* find */
+		sub	\irqnr, \irqnr, \tmp
+		ldr	\tmp, =IO_ADDRESS(AST_SCU_BASE)
+		str	\irqnr, [\tmp, #0x44]
+                cmp     \irqnr, #64
+4000:		/* done */                
+		.endm
+#else
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+/* FIXME: should not be using soo many LDRs here */
+		ldr	\irqnr, =IO_ADDRESS(AST_VIC_BASE)
+		ldr	\irqstat, [\irqnr, #ASPEED_VIC_STATUS_OFFSET]		@ get masked status
+
+		mov	\irqnr, #0
+1001:		tst	\irqstat, #1
+		bne	1002f
+		add	\irqnr, \irqnr, #1
+		mov	\irqstat, \irqstat, lsr #1
+		cmp	\irqnr, #31
+		bcc	1001b
+1002:		/* EQ will be set if we reach 31 */
+		.endm
+		
+#endif
+#else
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+		/*********************************************/
+		/* load VIC (VIC1) status value into irqstat */
+		/*********************************************/
+		ldr		\irqnr, 	=IO_ADDRESS(MVP2_VIC_BASE)
+		ldr		\irqstat,	[\irqnr, #MVP2_VIC_STATUS_OFFSET]
+
+
+		/**********************************************/
+		/* check each status bit and start from bit 0 */
+		/**********************************************/
+		mov		\irqnr,		#0
+1000:	tst		\irqstat,	#1		/* Check irqstat[irqnr] is 1 or not.  */
+		bne		1100f				/* If irqstat[irqnr] is 1, service    */
+									/* this interrupt.                    */
+1001:
+		/* check next bit */
+		add		\irqnr,		\irqnr,		#1
+		mov		\irqstat,	\irqstat,	lsr #1
+
+		cmp		\irqnr,		#32	/* If irqnr is number 32, all bits on VIC1 */
+		beq		1300f			/* have been checked and leave this macro. */
+								/* Note that the Zero bit should be 1.     */
+
+		bne		1000b			/* continue to check next bit */
+
+
+
+1100:	ldr		\irqstat,	=INT_VIC2IRQ		/* interrupt from VIC2? */
+		cmp		\irqnr,		\irqstat
+
+		bne		1300f		/* Interupt isn't from VIC2 (i.e. irqnr != INT_VIC2IRQ). */
+							/* Leave this macro with irqnr isn't changed and keep Zero */
+							/* flag not set */
+
+
+		/***************************************/
+		/* load VIC2 status value into irqstat */
+		/***************************************/
+#if 0
+		ldr		\irqnr, 	=IO_ADDRESS(MVP2_VIC2_BASE)
+		ldr		\irqstat,	[\irqnr, #MVP2_VIC_STATUS_OFFSET]
+#else
+		ldr		\irqnr, 	=IO_ADDRESS(MVP2_VIC_BASE)
+		ldr		\irqstat,	=0x1000
+		add		\irqnr,		\irqnr,		\irqstat
+		ldr		\irqstat,	[\irqnr, #MVP2_VIC_STATUS_OFFSET]
+#endif
+
+		/***********************************************/
+		/* Check each status bit and start from bit 0. */
+		/* Note that bit 0 in VIC2 is IRQ number 32.   */
+		/***********************************************/
+		mov		\irqnr,		#32
+1200:	tst		\irqstat,	#1
+		bne		1300f
+
+
+		/* check next bit */
+		add		\irqnr,		\irqnr,		#1
+		mov		\irqstat,	\irqstat,	lsr #1
+
+		cmp		\irqnr,		#64		/* If irqnr isn't reach 64 */
+		bne		1200b				/* continue check irqstat. */
+
+
+
+		/*************************************************************************/
+		/* Examine all the other interrupt bits larger than INT_VIC2IRQ on VIC1. */
+		/*************************************************************************/
+		ldr		\irqnr, 	=IO_ADDRESS(MVP2_VIC_BASE)
+		ldr		\irqstat,	[\irqnr, #MVP2_VIC_STATUS_OFFSET]
+		mov		\irqnr,		#INT_VIC2IRQ
+		mov		\irqstat,	\irqstat,	lsr #INT_VIC2IRQ
+		b		1001b
+
+		/* TODO : if needed */
+		/* All interrupt bits on VIC2 have been checked and no bit with value */
+		/* 1 is found. Write 1 to EdgeClearReg[INT_VIC2IRQ] to clear interrupt. */
+
+1300:
+		.endm
+
+#endif
+
+
+
+		.macro	irq_prio_table
+		.endm
+
diff --git a/arch/arm/mach-aspeed/include/mach/ftgmac100_drv.h b/arch/arm/mach-aspeed/include/mach/ftgmac100_drv.h
new file mode 100644
index 0000000..40a59e3
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/ftgmac100_drv.h
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ */
+
+/* store this information for the driver.. */
+
+struct ftgmac100_eth_data
+{
+	unsigned char	dev_addr[6];	//MAC address
+	unsigned char	phy_addr;		//Phy Address
+	unsigned char	phy_id;			//Phy ID
+	unsigned char 	DF_support;		//Defragment support
+	unsigned long	NCSI_support;
+	unsigned long	INTEL_NCSI_EVA_support;	
+};
diff --git a/arch/arm/mach-aspeed/include/mach/gpio.h b/arch/arm/mach-aspeed/include/mach/gpio.h
new file mode 100644
index 0000000..9ff3863
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/gpio.h
@@ -0,0 +1,352 @@
+/*
+ * arch/arm/mach-aspeed/include/mach/gpio.h
+ *
+ * Support functions for ASPEED GPIO
+ *
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Written by Ryan Chen <ryan_chen@aspeedtech.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
+ *
+ */
+
+#ifndef __ASM_ARCH_ASPEED_GPIO_H
+#define __ASM_ARCH_ASPEED_GPIO_H
+
+#include <linux/kernel.h>
+#include <mach/irqs.h>
+#include <plat/aspeed.h>
+
+/*************************************************************/
+#define GPIO_PORTA							0x0
+#define GPIO_PORTB							0x1
+#define GPIO_PORTC							0x2
+#define GPIO_PORTD							0x3
+#define GPIO_PORTE							0x4
+#define GPIO_PORTF							0x5
+#define GPIO_PORTG							0x6
+#define GPIO_PORTH							0x7
+#define GPIO_PORTI							0x8
+#define GPIO_PORTJ							0x9
+#define GPIO_PORTK							0xa
+#define GPIO_PORTL							0xb
+#define GPIO_PORTM							0xc
+#define GPIO_PORTN							0xd
+#define GPIO_PORTO							0xe
+#define GPIO_PORTP							0xf
+#define GPIO_PORTQ							0x10
+#define GPIO_PORTR							0x11
+#define GPIO_PORTS							0x12
+//AST2300 didn't have PORT TT
+#define GPIO_PORTT							0x13
+#if defined(AST_SOC_G4) || defined(CONFIG_AST2400_BMC)
+#define GPIO_PORTU							0x14
+#define GPIO_PORTV							0x15
+#define GPIO_PORTW							0x16
+#define GPIO_PORTX							0x17
+#define GPIO_PORTY							0x18
+#define GPIO_PORTZ							0x19
+#define GPIO_PORTAA							0x1a
+#define GPIO_PORTAB							0x1b
+#endif
+
+#define GPIO_PER_PORT_PIN_NUM				8
+
+#define GPIO_INPUT_MODE						0
+#define GPIO_OUTPUT_MODE					1
+
+#define GPIO_RISING_EDGE					1
+#define GPIO_FALLING_EDGE					0
+
+#define GPIO_LEVEL_HIGH						1
+#define GPIO_LEVEL_LOW						1
+
+#define GPIO_EDGE_MODE						0
+#define GPIO_LEVEL_MODE						1
+
+#define GPIO_EDGE_LEVEL_MODE				0
+#define GPIO_DUAL_EDGE_MODE					1
+
+#define GPIO_NO_DEBOUNCE					0
+#define GPIO_DEBOUNCE_TIMER0				2		//GPIO 50 as debounce timer
+#define GPIO_DEBOUNCE_TIMER1				1		//GPIO 54 as debounce timer
+#define GPIO_DEBOUNCE_TIMER2				3		//GPIO 58 as debounce timer
+
+#define GPIO_CMD_ARM						0
+#define GPIO_CMD_LPC						1		
+#define GPIO_CMD_COPROCESSOR				2
+
+#define PIN_GPIOA0						(0)
+#define PIN_GPIOA1						(1)
+#define PIN_GPIOA2						(2)
+#define PIN_GPIOA3						(3)
+#define PIN_GPIOA4						(4)
+#define PIN_GPIOA5						(5)
+#define PIN_GPIOA6						(6)
+#define PIN_GPIOA7						(7)
+#define PIN_GPIOB0						(8)
+#define PIN_GPIOB1						(9)
+#define PIN_GPIOB2						(10)
+#define PIN_GPIOB3						(11)
+#define PIN_GPIOB4						(12)
+#define PIN_GPIOB5						(13)
+#define PIN_GPIOB6						(14)
+#define PIN_GPIOB7						(15)
+#define PIN_GPIOC0						(16)
+#define PIN_GPIOC1						(17)
+#define PIN_GPIOC2						(18)
+#define PIN_GPIOC3						(19)
+#define PIN_GPIOC4						(20)
+#define PIN_GPIOC5						(21)
+#define PIN_GPIOC6						(22)
+#define PIN_GPIOC7						(23)
+#define PIN_GPIOD0						(24)
+#define PIN_GPIOD1						(25)
+#define PIN_GPIOD2						(26)
+#define PIN_GPIOD3						(27)
+#define PIN_GPIOD4						(28)
+#define PIN_GPIOD5						(29)
+#define PIN_GPIOD6						(30)
+#define PIN_GPIOD7						(31)
+#define PIN_GPIOE0						(32)
+#define PIN_GPIOE1						(33)
+#define PIN_GPIOE2						(34)
+#define PIN_GPIOE3						(35)
+#define PIN_GPIOE4						(36)
+#define PIN_GPIOE5						(37)
+#define PIN_GPIOE6						(38)
+#define PIN_GPIOE7						(39)
+#define PIN_GPIOF0						(40)
+#define PIN_GPIOF1						(41)
+#define PIN_GPIOF2						(42)
+#define PIN_GPIOF3						(43)
+#define PIN_GPIOF4						(44)
+#define PIN_GPIOF5						(45)
+#define PIN_GPIOF6						(46)
+#define PIN_GPIOF7						(47)
+#define PIN_GPIOG0						(48)
+#define PIN_GPIOG1						(49)
+#define PIN_GPIOG2						(50)
+#define PIN_GPIOG3						(51)
+#define PIN_GPIOG4						(52)
+#define PIN_GPIOG5						(53)
+#define PIN_GPIOG6						(54)
+#define PIN_GPIOG7						(55)
+#define PIN_GPIOH0						(56)
+#define PIN_GPIOH1						(57)
+#define PIN_GPIOH2						(58)
+#define PIN_GPIOH3						(59)
+#define PIN_GPIOH4						(60)
+#define PIN_GPIOH5						(61)
+#define PIN_GPIOH6						(62)
+#define PIN_GPIOH7						(63)
+#define PIN_GPIOI0						(64)
+#define PIN_GPIOI1						(65)
+#define PIN_GPIOI2						(66)
+#define PIN_GPIOI3						(67)
+#define PIN_GPIOI4						(68)
+#define PIN_GPIOI5						(69)
+#define PIN_GPIOI6						(70)
+#define PIN_GPIOI7						(71)
+#define PIN_GPIOJ0						(72)
+#define PIN_GPIOJ1						(73)
+#define PIN_GPIOJ2						(74)
+#define PIN_GPIOJ3						(75)
+#define PIN_GPIOJ4						(76)
+#define PIN_GPIOJ5						(77)
+#define PIN_GPIOJ6						(78)
+#define PIN_GPIOJ7						(79)
+#define PIN_GPIOK0						(80)
+#define PIN_GPIOK1						(81)
+#define PIN_GPIOK2						(82)
+#define PIN_GPIOK3						(83)
+#define PIN_GPIOK4						(84)
+#define PIN_GPIOK5						(85)
+#define PIN_GPIOK6						(86)
+#define PIN_GPIOK7						(87)
+#define PIN_GPIOL0						(88)
+#define PIN_GPIOL1						(89)
+#define PIN_GPIOL2						(90)
+#define PIN_GPIOL3						(91)
+#define PIN_GPIOL4						(92)
+#define PIN_GPIOL5						(93)
+#define PIN_GPIOL6						(94)
+#define PIN_GPIOL7						(95)
+#define PIN_GPIOM0						(96)
+#define PIN_GPIOM1						(97)
+#define PIN_GPIOM2						(98)
+#define PIN_GPIOM3						(99)
+#define PIN_GPIOM4						(100)
+#define PIN_GPIOM5						(101)
+#define PIN_GPIOM6						(102)
+#define PIN_GPIOM7						(103)
+#define PIN_GPION0						(104)
+#define PIN_GPION1						(105)
+#define PIN_GPION2						(106)
+#define PIN_GPION3						(107)
+#define PIN_GPION4						(108)
+#define PIN_GPION5						(109)
+#define PIN_GPION6						(110)
+#define PIN_GPION7						(111)
+#define PIN_GPIOO0						(112)
+#define PIN_GPIOO1						(113)
+#define PIN_GPIOO2						(114)
+#define PIN_GPIOO3						(115)
+#define PIN_GPIOO4						(116)
+#define PIN_GPIOO5						(117)
+#define PIN_GPIOO6						(118)
+#define PIN_GPIOO7						(119)
+#define PIN_GPIOP0						(120)
+#define PIN_GPIOP1						(121)
+#define PIN_GPIOP2						(122)
+#define PIN_GPIOP3						(123)
+#define PIN_GPIOP4						(124)
+#define PIN_GPIOP5						(125)
+#define PIN_GPIOP6						(126)
+#define PIN_GPIOP7						(127)
+#define PIN_GPIOQ0						(128)
+#define PIN_GPIOQ1						(129)
+#define PIN_GPIOQ2						(130)
+#define PIN_GPIOQ3						(131)
+#define PIN_GPIOQ4						(132)
+#define PIN_GPIOQ5						(133)
+#define PIN_GPIOQ6						(134)
+#define PIN_GPIOQ7						(135)
+#define PIN_GPIOR0						(136)
+#define PIN_GPIOR1						(137)
+#define PIN_GPIOR2						(138)
+#define PIN_GPIOR3						(139)
+#define PIN_GPIOR4						(140)
+#define PIN_GPIOR5						(141)
+#define PIN_GPIOR6						(142)
+#define PIN_GPIOR7						(143)
+#define PIN_GPIOS0						(144)
+#define PIN_GPIOS1						(145)
+#define PIN_GPIOS2						(146)
+#define PIN_GPIOS3						(147)
+#define PIN_GPIOS4						(148)
+#define PIN_GPIOS5						(149)
+#define PIN_GPIOS6						(150)
+#define PIN_GPIOS7						(151)
+#if defined(AST_SOC_G4) || defined(CONFIG_AST2400_BMC)
+#define PIN_GPIOT0						(152)
+#define PIN_GPIOT1						(153)
+#define PIN_GPIOT2						(154)
+#define PIN_GPIOT3						(155)
+#define PIN_GPIOT4						(156)
+#define PIN_GPIOT5						(157)
+#define PIN_GPIOT6						(158)
+#define PIN_GPIOT7						(159)
+#define PIN_GPIOU0						(161)
+#define PIN_GPIOU1						(162)
+#define PIN_GPIOU2						(163)
+#define PIN_GPIOU3						(164)
+#define PIN_GPIOU4						(165)
+#define PIN_GPIOU5						(166)
+#define PIN_GPIOU6						(167)
+#define PIN_GPIOU7						(168)
+#define PIN_GPIOV0						(169)
+#define PIN_GPIOV1						(170)
+#define PIN_GPIOV2						(171)
+#define PIN_GPIOV3						(172)
+#define PIN_GPIOV4						(173)
+#define PIN_GPIOV5						(174)
+#define PIN_GPIOV6						(175)
+#define PIN_GPIOV7						(176)
+#define PIN_GPIOW0						(177)
+#define PIN_GPIOW1						(178)
+#define PIN_GPIOW2						(179)
+#define PIN_GPIOW3						(181)
+#define PIN_GPIOW4						(182)
+#define PIN_GPIOW5						(183)
+#define PIN_GPIOW6						(184)
+#define PIN_GPIOW7						(185)
+#define PIN_GPIOX0						(186)
+#define PIN_GPIOX1						(187)
+#define PIN_GPIOX2						(188)
+#define PIN_GPIOX3						(189)
+#define PIN_GPIOX4						(190)
+#define PIN_GPIOX5						(191)
+#define PIN_GPIOX6						(192)
+#define PIN_GPIOX7						(193)
+#define PIN_GPIOY0						(194)
+#define PIN_GPIOY1						(195)
+#define PIN_GPIOY2						(196)
+#define PIN_GPIOY3						(197)
+#define PIN_GPIOY4						(198)
+#define PIN_GPIOY5						(199)
+#define PIN_GPIOY6						(200)
+#define PIN_GPIOY7						(201)
+#define PIN_GPIOZ0						(202)
+#define PIN_GPIOZ1						(203)
+#define PIN_GPIOZ2						(204)
+#define PIN_GPIOZ3						(205)
+#define PIN_GPIOZ4						(206)
+#define PIN_GPIOZ5						(207)
+#define PIN_GPIOZ6						(208)
+#define PIN_GPIOZ7						(209)
+#define PIN_GPIOAA0						(210)
+#define PIN_GPIOAA1						(211)
+#define PIN_GPIOAA2						(212)
+#define PIN_GPIOAA3						(213)
+#define PIN_GPIOAA4						(214)
+#define PIN_GPIOAA5						(215)
+#define PIN_GPIOAA6						(216)
+#define PIN_GPIOAA7						(217)
+#define PIN_GPIOBB0						(218)
+#define PIN_GPIOBB1						(219)
+#define PIN_GPIOBB2						(220)
+#define PIN_GPIOBB3						(221)
+#define PIN_GPIOBB4						(222)
+#define PIN_GPIOBB5						(223)
+#define PIN_GPIOBB6						(224)
+#define PIN_GPIOBB7						(225)
+#endif
+/*************************************************************/
+#ifndef __ASSEMBLY__
+
+/* callable at any time */
+extern int ast_set_gpio_value(unsigned gpio_pin, int value);
+extern int ast_get_gpio_value(unsigned gpio_pin);
+
+/*-------------------------------------------------------------------------*/
+
+/* wrappers for "new style" GPIO calls. the old AT91-specfic ones should
+ * eventually be removed (along with this errno.h inclusion), and the
+ * gpio request/free calls should probably be implemented.
+ */
+
+//extern int gpio_direction_input(unsigned gpio);
+//extern int gpio_direction_output(unsigned gpio, int value);
+
+static inline int gpio_get_value(unsigned gpio)
+{
+	return ast_get_gpio_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+	ast_set_gpio_value(gpio, value);
+}
+
+#include <asm-generic/gpio.h>		/* cansleep wrappers */
+
+#define gpio_to_irq(gpio)	(IRQ_GPIO_CHAIN_START + (gpio))
+#define irq_to_gpio(irq)	((irq) - IRQ_GPIO_CHAIN_START)
+
+#endif	/* __ASSEMBLY__ */
+
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/hardware.h b/arch/arm/mach-aspeed/include/mach/hardware.h
new file mode 100644
index 0000000..be3f23d
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/hardware.h
@@ -0,0 +1,51 @@
+/*
+ *  hardware.h
+ *
+ * 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_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <mach/platform.h>
+
+/*
+ * Where in virtual memory the IO devices (timers, system controllers
+ * and so on)
+ */
+
+#define IO_BASE					0xF8000000                 // VA of IO
+/*#define IO_BASE2				0xE0000000                 // VA of IO2 (AST1070) */
+
+#ifdef CONFIG_AST_PCIE_EXT
+#define ASPEED_IO_START2		AST_PCIE_WIN_BASE
+#else
+#define ASPEED_IO_START2		AST_LPC_BRIDGE
+#endif
+
+/* macro to get at IO space when running virtually */
+//#define IO_ADDRESS(x) (((x) >> 4) + IO_BASE) 
+/*#define IO_ADDRESS(x)  (x - 0x10000000 + IO_BASE)  */
+#define IO_ADDRESS(x)  (x - 0x1e600000 + IO_BASE) 
+/*#define IO_ADDRESS2(x) (x - ASPEED_IO_START2 + IO_BASE2) */
+
+//PCIE
+#ifdef CONFIG_AST_PCIE
+#define PCIBIOS_MIN_IO		0x0
+#define PCIBIOS_MIN_MEM		0x0
+#define pcibios_assign_all_busses()	1
+#endif
+
+#endif	/* __ASM_ARCH_HARDWARE_H END */
+
diff --git a/arch/arm/mach-aspeed/include/mach/io.h b/arch/arm/mach-aspeed/include/mach/io.h
new file mode 100644
index 0000000..baf86d2
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/io.h
@@ -0,0 +1,28 @@
+/*
+ *  io.h
+ *
+ * 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
+
+#include <mach/hardware.h>
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a)			((void __iomem *)(a))
+#define __mem_pci(a)            (a)
+#define __mem_isa(a)            (a)
+#endif
+
diff --git a/arch/arm/mach-aspeed/include/mach/irqs.h b/arch/arm/mach-aspeed/include/mach/irqs.h
new file mode 100644
index 0000000..d133251
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/irqs.h
@@ -0,0 +1,61 @@
+/*
+ *  arch/arm/plat-aspeed/include/plat/irqs.h
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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 <plat/aspeed.h>
+
+#if defined(CONFIG_ARCH_AST1010)
+#include <mach/ast1010_irqs.h>
+#elif defined(CONFIG_ARCH_AST1510)
+#include <mach/ast1510_irqs.h>
+#elif defined(CONFIG_ARCH_AST1520)
+#include <mach/ast1520_irqs.h>
+#elif defined(CONFIG_ARCH_AST2000)
+#include <mach/ast2000_irqs.h>
+#elif defined(CONFIG_ARCH_AST2100) 
+#include <mach/ast2100_irqs.h>
+#elif defined(CONFIG_ARCH_AST2200) 
+#include <mach/ast2200_irqs.h>
+#elif defined(CONFIG_ARCH_AST2300)
+#include <mach/ast2300_irqs.h>
+#elif defined(CONFIG_ARCH_AST2400)
+#include <mach/ast2400_irqs.h>
+#elif defined(CONFIG_ARCH_AST2500)
+#include <mach/ast2500_irqs.h>
+#elif defined(CONFIG_ARCH_AST3100)
+#include <mach/ast3100_irqs.h>
+#elif defined(CONFIG_ARCH_AST3200)
+#include <mach/ast3200_irqs.h>
+#else
+#err "no define for irqs.h"
+#endif
+
+#include <mach/ast_gpio_irqs.h>
+//#include <mach/ast_lpc_irqs.h>
+
+/*********************************************************************************/
+//CVIC
+#if defined(CONFIG_ARCH_AST1070)
+//Companion chip irq
+#include <mach/ast1070_irqs.h>
+#endif
+
+#if defined(CONFIG_AST2400_BMC)
+#include <mach/ext_ast2400_irqs.h>
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/memory.h b/arch/arm/mach-aspeed/include/mach/memory.h
new file mode 100644
index 0000000..d9927b2
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/memory.h
@@ -0,0 +1,48 @@
+/*
+ *  memory.h
+ *
+ * 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 <mach/platform.h>
+#include <plat/aspeed.h>
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#if defined(AST_SOC_G3) || defined(AST_SOC_G4)
+#define PHYS_OFFSET	UL(0x40000000)
+#define BUS_OFFSET	UL(0x40000000)
+#elif defined(AST_SOC_G5)
+#define PHYS_OFFSET     UL(0x80000000)
+#define BUS_OFFSET      UL(0x80000000)
+#else
+#define PHYS_OFFSET     UL(0x40000000)
+#define BUS_OFFSET      UL(0x40000000)
+#endif
+
+/*
+ * 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.
+ */
+#define __virt_to_bus(x)        (x - PAGE_OFFSET + BUS_OFFSET)
+#define __bus_to_virt(x)        (x - BUS_OFFSET + PAGE_OFFSET)
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/platform.h b/arch/arm/mach-aspeed/include/mach/platform.h
new file mode 100644
index 0000000..8951ffc
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/platform.h
@@ -0,0 +1,66 @@
+/*
+ * 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 _AST_PLATFORM_H_
+#define _AST_PLATFORM_H_                 1
+
+#define AST_PLL_25MHZ			25000000
+#define AST_PLL_24MHZ			24000000
+#define AST_PLL_12MHZ			12000000
+
+#define AST_IO_START                 0x1E600000
+#define AST_IO_SIZE                  0x00200000
+
+/*********************************************************************************/
+#if defined(CONFIG_ARCH_AST1520)
+#include <mach/ast1520_platform.h>
+#elif defined(CONFIG_ARCH_AST2000)
+#include <mach/ast2000_platform.h>
+#elif defined(CONFIG_ARCH_AST2100)
+#include <mach/ast2100_platform.h>
+#elif defined(CONFIG_ARCH_AST2200)
+#include <mach/ast2200_platform.h>
+#elif defined(CONFIG_ARCH_AST2300)
+#include <mach/ast2300_platform.h>
+#elif defined(CONFIG_ARCH_AST2400)
+#include <mach/ast2400_platform.h>
+#elif defined(CONFIG_ARCH_AST2500)
+#include <mach/ast2500_platform.h>
+#elif defined(CONFIG_ARCH_AST3200)
+#include <mach/ast3200_platform.h>
+#else
+#err "No define for platform.h"
+#endif
+/*********************************************************************************/
+/* Companion Base Address */
+#if defined(CONFIG_ARCH_AST1070)
+#include <mach/ast1070_platform.h>
+#endif
+/*********************************************************************************/
+#define AST_CS0_DEF_BASE		               	  0x20000000	/* CS0 */
+#define AST_CS1_DEF_BASE		               	  0x24000000	/* CS1 */
+#define AST_CS2_DEF_BASE		               	  0x26000000	/* CS2 */
+#define AST_CS3_DEF_BASE		               	  0x28000000	/* CS3 */
+#define AST_CS4_DEF_BASE		               	  0x2a000000	/* CS4 */
+
+#define AST_NOR_SIZE		               	  		0x01000000	/* AST2300 NOR size 16MB */
+
+/*
+ * Watchdog
+ */
+#define AST_WDT_VA_BASE		(IO_ADDRESS(AST_WDT_BASE))
+ 
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/system.h b/arch/arm/mach-aspeed/include/mach/system.h
new file mode 100644
index 0000000..96e90da
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/system.h
@@ -0,0 +1,44 @@
+/*
+ *  system.h
+ *
+ * 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_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/hardware.h>
+#include <asm/io.h>
+#include <mach/ast_wdt.h>
+
+static inline void arch_idle(void)
+{
+	/*
+	 * This should do all the clock switching
+	 * and wait for interrupt tricks
+	 */
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+	/*
+	 * Use WDT to restart system
+	 */
+#if defined(CONFIG_AST_WATCHDOG) || defined(CONFIG_AST_WATCHDOG_MODULE)	
+	ast_soc_wdt_reset();
+#endif
+}
+
+#endif
diff --git a/arch/arm/mach-aspeed/include/mach/time.h b/arch/arm/mach-aspeed/include/mach/time.h
new file mode 100644
index 0000000..973a0b0
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/time.h
@@ -0,0 +1,73 @@
+/*
+ *  time.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <asm/system.h>
+#include <asm/mach/time.h>
+#include <asm/param.h>
+
+/*
+ * How long is the timer interval?
+ */
+#define TIMER_INTERVAL	(ASPEED_TIMER_CLKRATE / HZ)
+#define TIMER_RELOAD	(TIMER_INTERVAL)
+#define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
+
+/*
+ * Timer
+ */
+#define ASPEED_TIMER0_OFFSET		0x0000		/* Timer0 Offset */
+#define ASPEED_TIMER1_OFFSET		0x0010		/* Timer1 Offset */
+#define ASPEED_TIMER2_OFFSET		0x0020		/* Timer2 Offset */
+#define ASPEED_TIMERRC_OFFSET		0x0030		/* Timer RC Offset */
+
+#define ASPEED_TIMER_CLKRATE		(ASPEED_EXTCLK)
+#define ASPEED_EXTCLK			(1*1000*1000)	/* 1M */
+
+/*
+ * Ticks
+ */
+//#define TICKS_PER_uSEC                  40 // IP Cam
+//#define TICKS_PER_uSEC                  24 // FPGA
+#define TICKS_PER_uSEC                  1		/* ASPEED_EXTCLK / 10 ^ 6 */
+
+#define mSEC_1                          1000
+#define mSEC_5                          (mSEC_1 * 5)
+#define mSEC_10                         (mSEC_1 * 10)
+#define mSEC_25                         (mSEC_1 * 25)
+#define SEC_1                           (mSEC_1 * 1000)
+
+/*
+ * Timer Control
+ */
+#define TIMER0_ENABLE   0x0001
+#define TIMER1_ENABLE   0x0010
+#define TIMER2_ENABLE   0x0100
+
+#define TIMER0_RefExt   0x0002
+#define TIMER1_RefExt   0x0020
+#define TIMER2_RefExt   0x0200
+
+/*
+ * What does it look like?
+ */
+typedef struct TimerStruct {
+	unsigned long TimerValue;
+	unsigned long TimerLoad;
+	unsigned long TimerMatch1;
+	unsigned long TimerMatch2;
+} TimerStruct_t;
+
diff --git a/arch/arm/mach-aspeed/include/mach/timex.h b/arch/arm/mach-aspeed/include/mach/timex.h
new file mode 100644
index 0000000..e907a30
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/timex.h
@@ -0,0 +1,21 @@
+/*
+ *  timex.h
+ *
+ *  Integrator architecture timex specifications
+ *
+ * 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 CLOCK_TICK_RATE		(50000000 / 16)
diff --git a/arch/arm/mach-aspeed/include/mach/uncompress.h b/arch/arm/mach-aspeed/include/mach/uncompress.h
new file mode 100644
index 0000000..896b854
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/uncompress.h
@@ -0,0 +1,38 @@
+/*
+ *  uncompress.h
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/platform.h>
+#include <mach/aspeed_serial.h>
+
+#define UART_PUT_CHAR   (*(volatile unsigned char *)(AST_UART0_BASE + UART_THR))
+#define UART_GET_LSR   (*(volatile unsigned char *)(AST_UART0_BASE + UART_LSR))
+
+static void putc(int c)
+{
+
+	/* wait for space in the UART's transmitter */
+	while (!(UART_GET_LSR & UART_LSR_THRE))
+		barrier();
+	
+	/* send the character out. */
+	UART_PUT_CHAR = c;
+}
+
+static inline void flush(void)
+{
+	while (UART_GET_LSR & (1 << 3))
+			 barrier();
+}
+
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-aspeed/include/mach/vmalloc.h b/arch/arm/mach-aspeed/include/mach/vmalloc.h
new file mode 100644
index 0000000..3706cf1
--- /dev/null
+++ b/arch/arm/mach-aspeed/include/mach/vmalloc.h
@@ -0,0 +1,29 @@
+/*
+ *  vmalloc.h
+ *
+ * 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. ;)
+ */
+#if 0
+#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)
+#else
+#define VMALLOC_END                     0xf8000000UL
+#endif
\ No newline at end of file
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index ab5f7a2..d7b499a 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -180,7 +180,7 @@ config CPU_ARM925T
 # ARM926T
 config CPU_ARM926T
 	bool "Support ARM926T processor"
-	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || \
+	depends on ARCH_ASPEED || ARCH_INTEGRATOR || ARCH_VERSATILE_PB || \
 		MACH_VERSATILE_AB || ARCH_OMAP730 || \
 		ARCH_OMAP16XX || MACH_REALVIEW_EB || \
 		ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || \
@@ -188,7 +188,7 @@ config CPU_ARM926T
 		ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || \
 		ARCH_AT91SAM9G20 || ARCH_AT91CAP9 || \
 		ARCH_NS9XXX || ARCH_DAVINCI || ARCH_MX2
-	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || \
+	default y if ARCH_ASPEED || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || \
 		ARCH_OMAP730 || ARCH_OMAP16XX || \
 		ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || \
 		ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || \
diff --git a/arch/arm/plat-aspeed/Makefile b/arch/arm/plat-aspeed/Makefile
new file mode 100644
index 0000000..faba830
--- /dev/null
+++ b/arch/arm/plat-aspeed/Makefile
@@ -0,0 +1,35 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y 			+= irq.o timer.o devs.o ast-scu.o ast-sdmc.o
+
+obj-$(CONFIG_ARCH_AST1070) += ast1070_irq.o ast1070-scu.o ast1070-uart-dma.o dev-ci2c.o dev-cuart.o dev-clpc.o
+
+obj-$(CONFIG_AST_I2C_SLAVE_MODE) += i2c-slave-eeprom.o
+
+obj-$(CONFIG_AST2400_BMC) += ast2400-irq.o ast2400-scu.o dev-ast2400-uart.o #dev-ast2400-i2c.o
+
+#obj-n   := dummy.o
+#platform
+obj-y			+= dev-uart.o dev-vuart.o dev-wdt.o dev-rtc.o dev-gpio.o dev-sgpio.o
+
+#Storage
+obj-y 	                += dev-nor.o dev-nand.o dev-sdhci.o
+
+#bus
+obj-y                   += dev-i2c.o dev-spi.o dev-ehci.o dev-uhci.o dev-lpc.o dev-peci.o dev-kcs.o dev-mbx.o dev-snoop.o 
+
+#dev
+#obj-y			+= dev-udc11.o
+#net
+obj-y			+= dev-eth.o
+
+#hwmon
+obj-y                   += dev-pwm-fan.o dev-adc.o
+
+#video
+obj-y			+= dev-fb.o dev-video.o
+#obj-m                  :=
+#obj-n                  :=
+#obj-                   :=
diff --git a/arch/arm/plat-aspeed/ast-scu.c b/arch/arm/plat-aspeed/ast-scu.c
new file mode 100644
index 0000000..1f1dde2
--- /dev/null
+++ b/arch/arm/plat-aspeed/ast-scu.c
@@ -0,0 +1,1202 @@
+/********************************************************************************
+* File Name     : arch/arm/plat-aspeed/ast-scu.c 
+* Author         : Ryan Chen
+* Description   : AST SCU 
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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 
+
+CLK24M 
+ |
+ |--> H-PLL -->HCLK
+ |
+ |--> M-PLL -xx->MCLK
+ |
+ |--> V-PLL1 -xx->DCLK
+ |
+ |--> V-PLL2 -xx->D2CLK
+ |
+ |--> USB2PHY -->UTMICLK
+
+
+*   History      : 
+*    1. 2012/08/15 Ryan Chen Create
+* 
+********************************************************************************/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#include <mach/platform.h>
+#include <asm/io.h>
+
+#include <mach/hardware.h>
+
+#include <plat/ast-scu.h>
+#include <plat/regs-scu.h>
+
+//#define ASPEED_SCU_LOCK
+//#define ASPEED_SCU_DEBUG
+
+#ifdef ASPEED_SCU_DEBUG
+#define SCUDBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
+#else
+#define SCUDBUG(fmt, args...)
+#endif
+
+#define SCUMSG(fmt, args...) printk(fmt, ## args)
+
+static u32 ast_scu_base = IO_ADDRESS(AST_SCU_BASE);
+
+static inline u32 
+ast_scu_read(u32 reg)
+{
+	u32 val;
+		
+	val = readl(ast_scu_base + reg);
+	
+	SCUDBUG("ast_scu_read : reg = 0x%08x, val = 0x%08x\n", reg, val);
+	
+	return val;
+}
+
+static inline void
+ast_scu_write(u32 val, u32 reg) 
+{
+	SCUDBUG("ast_scu_write : reg = 0x%08x, val = 0x%08x\n", reg, val);
+#ifdef CONFIG_AST_SCU_LOCK
+	//unlock 
+	writel(SCU_PROTECT_UNLOCK, ast_scu_base);
+	writel(val, ast_scu_base + reg);
+	//lock
+	writel(0xaa,ast_scu_base);	
+#else
+	writel(val, ast_scu_base + reg);
+#endif
+}
+
+//SoC mapping Table 
+struct soc_id {
+	const char	* name;
+	u32	rev_id;
+};
+
+static struct soc_id soc_map_table[] = {
+	[0] = {
+		.name = "AST1100/AST2050-A0",
+		.rev_id = 0x00000200,
+	},
+	[1] = {
+		.name = "AST1100/AST2050-A1",
+		.rev_id = 0x00000201,
+	},
+	[2] = {
+		.name = "AST1100/AST2050-A2,3/AST2150-A0,1",
+		.rev_id = 0x00000202,
+	},
+	[3] = {
+		.name = "AST1510/AST2100-A0",
+		.rev_id = 0x00000300,
+	},
+	[4] = {
+		.name = "AST1510/AST2100-A1",
+		.rev_id = 0x00000301,
+	},
+	[5] = {
+		.name = "AST1510/AST2100-A2,3",
+		.rev_id = 0x00000302,
+	},
+	[6] = {
+		.name = "AST2200-A0,1",
+		.rev_id = 0x00000102,
+	},
+	[7] = {
+		.name = "AST2300-A0",
+		.rev_id = 0x01000003,
+	},
+	[8] = {
+		.name = "AST2300-A1",
+		.rev_id = 0x01010303,
+	},
+	[9] = {
+		.name = "AST1300-A1",
+		.rev_id = 0x01010003,
+	},
+	[10] = {
+		.name = "AST1050-A1",
+		.rev_id = 0x01010203,
+	},
+	[11] = {
+		.name = "AST2400-A0",
+		.rev_id = 0x02000303,
+	},
+	[12] = {
+		.name = "AST2400-A1",
+		.rev_id = 0x02010303,
+	},
+	[13] = {
+		.name = "AST1010-A0",
+		.rev_id = 0x03000003,
+	},
+	[14] = {
+		.name = "AST1010-A1",
+		.rev_id = 0x03010003,
+	},
+	[15] = {
+		.name = "AST1520-A0",
+		.rev_id = 0x03000003,
+	},
+	[16] = {
+		.name = "AST3200-A0",
+		.rev_id = 0x03000003,
+	},
+};
+
+//***********************************Initial control***********************************
+extern void
+ast_scu_reset_video(void)
+{
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_VIDEO, AST_SCU_RESET);
+	udelay(100);
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_VIDEO, AST_SCU_RESET);
+}
+
+EXPORT_SYMBOL(ast_scu_reset_video);
+
+extern void
+ast_scu_init_video(u8 dynamic_en)
+{
+	//Video Engine Clock Enable and Reset
+	//  Enable Clock & ECLK = inverse of (M-PLL / 2)
+	if(dynamic_en)
+		ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_VIDEO_SLOW_MASK) | SCU_CLK_VIDEO_SLOW_EN | SCU_CLK_VIDEO_SLOW_SET(0), AST_SCU_CLK_SEL);
+	else
+		ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_ECLK_SOURCE_MASK) | SCU_ECLK_SOURCE(2), AST_SCU_CLK_SEL);
+	
+	// Enable CLK
+	ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~(SCU_ECLK_STOP_EN | SCU_VCLK_STOP_EN), AST_SCU_CLK_STOP);	
+	mdelay(10);
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_VIDEO, AST_SCU_RESET);
+	udelay(100);
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_VIDEO, AST_SCU_RESET);
+}
+
+EXPORT_SYMBOL(ast_scu_init_video);
+
+extern void
+ast_scu_init_eth(u8 num)
+{
+	//AST2300 max clk to 125Mhz, AST2400 max clk to 198Mhz
+	if(ast_scu_read(AST_SCU_HW_STRAP1) && (SCU_HW_STRAP_MAC1_RGMII | SCU_HW_STRAP_MAC0_RGMII))	//RGMII --> H-PLL/6
+		ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_MAC_MASK) | SCU_CLK_MAC_DIV(2), AST_SCU_CLK_SEL);
+	else	//RMII --> H-PLL/10
+		ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_MAC_MASK) | SCU_CLK_MAC_DIV(4), AST_SCU_CLK_SEL);
+
+	//Set MAC delay Timing
+	ast_scu_write(0x2255, AST_SCU_MAC_CLK);	
+
+	switch(num) {
+		case 0:
+			ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_MAC0, 
+							AST_SCU_RESET);		
+			udelay(100);
+			ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_MAC0CLK_STOP_EN, 
+							AST_SCU_CLK_STOP);		
+			udelay(1000);
+			ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_MAC0, 
+							AST_SCU_RESET);		
+			
+			break;
+		case 1:
+			ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_MAC1, 
+							AST_SCU_RESET);			
+			udelay(100);
+			ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_MAC1CLK_STOP_EN, 
+							AST_SCU_CLK_STOP);		
+			udelay(1000);
+			ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_MAC1, 
+							AST_SCU_RESET);			
+			break;
+			
+	}		
+}
+
+
+extern void
+ast_scu_init_usb20(void)
+{
+	/* EHCI controller engine init. Process similar to VHub. */
+	/* Following reset sequence can resolve "vhub dead on first power on" issue on V4 board. */
+	//reset USB20
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_USB20, AST_SCU_RESET);
+
+	//enable USB20 clock
+	ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) | SCU_USB20_CLK_EN, AST_SCU_CLK_STOP);
+	mdelay(10);
+
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_USB20, AST_SCU_RESET);
+
+	udelay(500);
+
+//	printk("%x \n",ast_scu_read(AST_SCU_RESET));
+
+
+}
+
+EXPORT_SYMBOL(ast_scu_init_usb20);
+
+extern void
+ast_scu_init_uhci(void)
+{
+	//USB1.1 Host's Clock Enable and Reset
+	ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_USB11CLK_STOP_EN, AST_SCU_CLK_STOP);
+	mdelay(10);
+
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_USB11, AST_SCU_RESET);
+}
+
+EXPORT_SYMBOL(ast_scu_init_uhci);
+
+extern void
+ast_scu_init_udc11(void)
+{
+	//USB1.1 device Clock Enable and Reset
+	ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_UCLK_STOP_EN, AST_SCU_CLK_STOP);
+	mdelay(10);
+
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_USB11_HID, AST_SCU_RESET);
+}
+
+EXPORT_SYMBOL(ast_scu_init_udc11);
+
+///
+extern void
+ast_scu_init_sdhci(void)
+{
+	//SDHCI Host's Clock Enable and Reset
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_SD, AST_SCU_RESET);
+	
+	ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_SDCLK_STOP_EN, AST_SCU_CLK_STOP);
+	mdelay(10);
+
+	ast_scu_write(ast_scu_read(AST_SCU_CLK_SEL) | SCU_CLK_SD_EN, AST_SCU_CLK_SEL);
+	mdelay(10);
+
+	// SDCLK = H-PLL / 4
+	ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_SD_MASK) | SCU_CLK_SD_DIV(1), 
+		AST_SCU_CLK_SEL);
+	mdelay(10);
+	
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_SD, AST_SCU_RESET);
+}
+
+EXPORT_SYMBOL(ast_scu_init_sdhci);
+
+extern void
+ast_scu_init_i2c(void)
+{
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_I2C, AST_SCU_RESET);
+}
+
+EXPORT_SYMBOL(ast_scu_init_i2c);
+
+extern void
+ast_scu_init_pwm_tacho(void)
+{
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_PWM, AST_SCU_RESET);
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_PWM, AST_SCU_RESET);
+}
+
+EXPORT_SYMBOL(ast_scu_init_pwm_tacho);
+
+extern void
+ast_scu_init_adc(void)
+{
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_ADC, AST_SCU_RESET);
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_ADC, AST_SCU_RESET);
+}
+
+EXPORT_SYMBOL(ast_scu_init_adc);
+
+extern void
+ast_scu_init_peci(void)
+{
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_PECI, AST_SCU_RESET);
+	udelay(3);
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_PECI, AST_SCU_RESET);
+}
+
+EXPORT_SYMBOL(ast_scu_init_peci);
+
+extern void
+ast_scu_init_jtag(void)
+{
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_JTAG, AST_SCU_RESET);
+	udelay(3);
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_JTAG, AST_SCU_RESET);
+}
+
+EXPORT_SYMBOL(ast_scu_init_jtag);
+
+extern void
+ast_scu_init_lpc(void)
+{
+	//Note .. It have been enable in U-boot..... 
+//	ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_LPC, AST_SCU_RESET);
+
+	//enable LPC clock LHCLK = H-PLL/8
+	ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) | 
+					SCU_SET_LHCLK_DIV(3) | 
+					SCU_LHCLK_SOURCE_EN, 
+					AST_SCU_CLK_STOP);
+
+}
+
+EXPORT_SYMBOL(ast_scu_init_lpc);
+
+//////1 : lpc plus modes
+extern u8
+ast_scu_get_lpc_plus_enable(void)
+{
+	if(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & SCU_FUN_PIN_LPC_PLUS)
+		return 1;
+	else 
+		return 0;
+}
+
+EXPORT_SYMBOL(ast_scu_get_lpc_plus_enable);
+
+extern void
+ast_scu_init_crt(void)
+{
+	//enable D2 pll , //enable DVO (bit18) is VGA , enable DAC (bit16) is CRT
+#if defined(CONFIG_AST_DAC) || defined(CONFIG_AST_DVO)
+	ast_scu_write((ast_scu_read(AST_SCU_MISC1_CTRL) & ~(SCU_MISC_D2_PLL_DIS | SCU_MISC_DAC_MASK))
+				| SCU_MISC_DAC_SOURCE_CRT | SCU_MISC_DVO_SOURCE_CRT | SCU_MISC_2D_CRT_EN , AST_SCU_MISC1_CTRL);
+#elif defined(CONFIG_AST_DVO) 
+	ast_scu_write((ast_scu_read(AST_SCU_MISC1_CTRL) & ~(SCU_MISC_D2_PLL_DIS)) |
+				SCU_MISC_DVO_SOURCE_CRT| SCU_MISC_2D_CRT_EN, AST_SCU_MISC1_CTRL);
+#else //default(CONFIG_AST_DAC) 
+	ast_scu_write((ast_scu_read(AST_SCU_MISC1_CTRL) & ~(SCU_MISC_D2_PLL_DIS | SCU_MISC_DAC_MASK))
+				| SCU_MISC_DAC_SOURCE_CRT | SCU_MISC_2D_CRT_EN, AST_SCU_MISC1_CTRL);
+#endif
+	/* Set Delay 5 Compensation TODO ...*/
+	ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_VIDEO_DELAY_MASK) |
+						SCU_CLK_VIDEO_DELAY(5), AST_SCU_CLK_SEL);
+
+	/* Reset CRT */ 
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_CRT, AST_SCU_RESET);
+
+	//enable D2 CLK
+	ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_D2CLK_STOP_EN , AST_SCU_CLK_STOP);
+
+	udelay(10);
+	ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_CRT, AST_SCU_RESET);
+	
+}
+
+EXPORT_SYMBOL(ast_scu_init_crt);
+//***********************************CLK control***********************************
+extern void
+ast_scu_clk_stop(u32 clk_name,u8 stop_enable)
+{
+	switch(clk_name){
+		default:
+			SCUMSG("ERRO clk_name :%d \n",clk_name);
+			break;
+	}
+}
+
+EXPORT_SYMBOL(ast_scu_clk_stop);
+
+
+//***********************************CLK Information***********************************
+extern u32
+ast_get_clk_source(void)
+{
+	if(ast_scu_read(AST_SCU_HW_STRAP1) & CLK_25M_IN)
+		return AST_PLL_25MHZ;
+	else
+		return AST_PLL_24MHZ;
+}
+
+EXPORT_SYMBOL(ast_get_clk_source);
+
+
+extern u32
+ast_get_h_pll_clk(void)
+{
+	u32 speed,clk=0;
+	u32 h_pll_set = ast_scu_read(AST_SCU_H_PLL);
+
+	if(h_pll_set & SCU_H_PLL_OFF)
+		return 0;
+	
+	if(h_pll_set & SCU_H_PLL_PARAMETER) {
+		// Programming
+		clk = ast_get_clk_source();
+		if(h_pll_set & SCU_H_PLL_BYPASS_EN) {
+			return clk;
+		} else {
+			//OD == SCU24[4]
+			//OD = SCU_H_PLL_GET_DIV(h_pll_set);
+			//Numerator == SCU24[10:5]
+			//num = SCU_H_PLL_GET_NUM(h_pll_set);
+			//Denumerator == SCU24[3:0]
+			//denum = SCU_H_PLL_GET_DENUM(h_pll_set);
+
+			//hpll = 24MHz * (2-OD) * ((Numerator+2)/(Denumerator+1))
+			clk = ((clk * (2-SCU_H_PLL_GET_DIV(h_pll_set)) * (SCU_H_PLL_GET_NUM(h_pll_set)+2))/(SCU_H_PLL_GET_DENUM(h_pll_set)+1));
+		}
+	} else {
+		// HW Trap
+		speed = SCU_HW_STRAP_GET_H_PLL_CLK(ast_scu_read(AST_SCU_HW_STRAP1));
+		switch (speed) {
+			case 0:
+				clk = 384000000; 
+				break;
+			case 1:
+				clk = 360000000; 
+				break;
+			case 2:
+				clk = 336000000; 
+				break;
+			case 3:
+				clk = 408000000; 
+				break;
+			default:
+				BUG(); 
+				break;
+		}		
+	}
+	SCUDBUG("h_pll = %d\n",clk);
+	return clk;
+}
+
+EXPORT_SYMBOL(ast_get_h_pll_clk);
+
+extern u32
+ast_get_m_pll_clk(void)
+{
+	u32 clk=0;
+	u32 m_pll_set = ast_scu_read(AST_SCU_M_PLL);
+
+	if(m_pll_set & SCU_M_PLL_OFF)
+		return 0;
+	
+	// Programming
+	clk = ast_get_clk_source();
+	if(m_pll_set & SCU_M_PLL_BYPASS_EN) {
+		return clk;
+	} else {
+		//OD == SCU24[4]
+		//OD = SCU_M_PLL_GET_DIV(h_pll_set);
+		//Numerator == SCU24[10:5]
+		//num = SCU_M_PLL_GET_NUM(h_pll_set);
+		//Denumerator == SCU24[3:0]
+		//denum = SCU_M_PLL_GET_DENUM(h_pll_set);
+
+		//hpll = 24MHz * (2-OD) * ((Numerator+2)/(Denumerator+1))
+		clk = (clk * (2-SCU_M_PLL_GET_DIV(m_pll_set)) * ((SCU_M_PLL_GET_NUM(m_pll_set)+2)/(SCU_M_PLL_GET_DENUM(m_pll_set)+1)));
+	}
+	SCUDBUG("m_pll = %d\n",clk);
+	return clk;
+}
+
+EXPORT_SYMBOL(ast_get_m_pll_clk);
+
+extern u32
+ast_get_ahbclk(void)
+{
+	unsigned int div, hpll;
+
+	hpll = ast_get_h_pll_clk();
+	div = SCU_HW_STRAP_GET_CPU_AHB_RATIO(ast_scu_read(AST_SCU_HW_STRAP1));
+	switch(div) {
+		case 0:
+			div = 1;
+		break;
+		case 1:
+			div = 2;
+		break;
+		case 2:
+			div = 3;
+		break;
+		case 3:
+			div = 4;
+		break;
+		
+	}
+	
+	SCUDBUG("HPLL=%d, Div=%d, AHB CLK=%d\n", hpll, div, hpll/div);	
+	return (hpll/div);
+
+}
+EXPORT_SYMBOL(ast_get_ahbclk);
+
+extern u32
+ast_get_pclk(void)
+{
+	unsigned int div, hpll;
+
+	hpll = ast_get_h_pll_clk();
+	div = SCU_GET_PCLK_DIV(ast_scu_read(AST_SCU_CLK_SEL));
+	div = (div+1) << 1;
+	
+	SCUDBUG("HPLL=%d, Div=%d, PCLK=%d\n", hpll, div, hpll/div);	
+	return (hpll/div);
+
+}
+EXPORT_SYMBOL(ast_get_pclk);
+
+extern u32
+ast_get_lhclk(void)
+{
+	unsigned int div, hpll;
+	u32 clk_sel = ast_scu_read(AST_SCU_CLK_SEL);
+//FPGA AST1070 is default 100/2 Mhz input
+//	return 50000000;	
+	hpll = ast_get_h_pll_clk();
+	if(SCU_LHCLK_SOURCE_EN & clk_sel) {
+		div = SCU_GET_LHCLK_DIV(clk_sel);
+		switch(div) {
+			case 0:
+				div = 2;
+			break;
+			case 1:
+				div = 4;
+			break;
+			case 2:
+				div = 6;
+			break;
+			case 3:
+				div = 8;
+			break;
+			case 4:
+				div = 10;
+			break;
+			case 5:
+				div = 12;
+			break;
+			case 6:
+				div = 14;
+			break;
+			case 7:
+				div = 16;
+			break;			
+		}
+		
+		SCUDBUG("HPLL=%d, Div=%d, LHCLK = %d\n", hpll, div, hpll/div);	
+		return (hpll/div);
+	} else {
+		SCUMSG("LPC CLK not enable \n");
+		return 0;
+	}
+
+}
+
+EXPORT_SYMBOL(ast_get_lhclk);
+
+extern u32
+ast_get_d2_pll_clk(void)
+{
+	u32 clk=0;
+	u32 d2_pll_set = ast_scu_read(AST_SCU_D2_PLL);
+	u32 OD,NUM,DENUM,PD,PD2;
+
+	if(d2_pll_set & SCU_D2_PLL_OFF)
+		return 0;
+
+	// Programming
+	clk = ast_get_clk_source();
+	if(d2_pll_set & SCU_D2_PLL_BYPASS_EN) {
+		return clk;
+	} else {
+		NUM = SCU_D2_PLL_GET_NUM(d2_pll_set);
+		DENUM = SCU_D2_PLL_GET_DENUM(d2_pll_set);
+		OD = SCU_D2_PLL_GET_OD(d2_pll_set);
+		OD = (1 << (OD - 1));
+		PD = SCU_D2_PLL_GET_PD(d2_pll_set);
+		switch(PD) {
+			case 0:
+				PD = 1;
+				break;
+			case 1:
+				PD = 2;
+				break;
+			case 2:
+				PD = 2;
+				break;
+			case 3:
+				PD = 4;
+				break;
+		}
+		PD2 = SCU_D2_PLL_GET_PD2(d2_pll_set);
+		PD2 = PD2+1;
+//		printk("clk %d ,num %d ,denum %d ,od %d ,pd %d ,pd2 %d \n",clk, NUM , DENUM, OD, PD, PD2);
+		//hpll = 24MHz * (Numerator * 2) / (Denumerator * OD * PD * PD2)
+		clk = (clk * NUM * 2) / (DENUM* OD * PD * PD2);
+	}
+
+	SCUDBUG("d2_pll = %d\n",clk);
+	return clk;
+}
+
+EXPORT_SYMBOL(ast_get_d2_pll_clk);
+
+//Because value 0 is not allowed in SDIO12C D[15:8]: Host Control Settings #1 Register, we have to increase the maximum
+//host's clock in case that system will not ask host to set 1 in the sdhci_set_clock() function
+/*
+SCU7C: Silicon Revision ID Register
+D[31:24]: Chip ID
+0: AST2050/AST2100/AST2150/AST2200/AST3000
+1: AST2300
+
+D[23:16] Silicon revision ID for AST2300 generation and later
+0: A0
+1: A1
+2: A2
+.
+.
+.
+FPGA revision starts from 0x80
+
+
+D[11:8] Bounding option
+
+D[7:0] Silicon revision ID for AST2050/AST2100 generation (for software compatible)
+0: A0
+1: A1
+2: A2
+3: A3
+.
+.
+FPGA revision starts from 0x08, 8~10 means A0, 11+ means A1, AST2300 should be assigned to 3
+*/
+
+extern u32
+ast_get_sd_clock_src(void)
+{
+	u32 clk=0, sd_div;
+
+#if defined(FPGA)
+		clk = 100000000;
+#else
+		clk = ast_get_h_pll_clk();
+		//get div
+		sd_div = SCU_CLK_SD_GET_DIV(ast_scu_read(AST_SCU_CLK_SEL));
+		SCUDBUG("div %d, sdclk =%d \n",((sd_div + 1) * 2),clk/((sd_div + 1) * 2));
+		clk /= ((sd_div + 1) * 2);
+		
+#endif
+	return clk;
+}
+
+EXPORT_SYMBOL(ast_get_sd_clock_src);
+
+extern void
+ast_scu_show_system_info (void)
+{
+	u32 h_pll, div;
+
+	h_pll = ast_get_h_pll_clk();
+	
+	div = SCU_HW_STRAP_GET_CPU_AHB_RATIO(ast_scu_read(AST_SCU_HW_STRAP1));
+	switch(div) {
+		case 0:
+			div = 1;
+		break;
+		case 1:
+			div = 2;
+		break;
+		case 2:
+			div = 3;
+		break;
+		case 3:
+			div = 4;
+		break;
+		
+	}
+
+	SCUMSG("CPU = %d MHz ,AHB = %d MHz (%d:1) \n", h_pll/1000000, h_pll/div/1000000,div); 
+
+	return ;
+}
+
+EXPORT_SYMBOL(ast_scu_show_system_info);
+
+//*********************************** Multi-function pin control ***********************************
+extern void
+ast_scu_multi_func_uart(u8 uart)
+{
+	switch(uart) {
+		case 1:
+			ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
+						SCU_FUN_PIN_UART1_RXD |
+						SCU_FUN_PIN_UART1_TXD |
+						SCU_FUN_PIN_UART1_NRTS |
+						SCU_FUN_PIN_UART1_NDTR |
+						SCU_FUN_PIN_UART1_NRI |
+						SCU_FUN_PIN_UART1_NDSR |
+						SCU_FUN_PIN_UART1_NDCD |
+						SCU_FUN_PIN_UART1_NCTS, 
+				AST_SCU_FUN_PIN_CTRL1); 
+			break;		
+		case 2:
+			ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
+						SCU_FUN_PIN_UART2_RXD |
+						SCU_FUN_PIN_UART2_TXD |
+						SCU_FUN_PIN_UART2_NRTS |
+						SCU_FUN_PIN_UART2_NDTR |
+						SCU_FUN_PIN_UART2_NRI |
+						SCU_FUN_PIN_UART2_NDSR |
+						SCU_FUN_PIN_UART2_NDCD |
+						SCU_FUN_PIN_UART2_NCTS, 
+				AST_SCU_FUN_PIN_CTRL1); 
+			break;		
+		case 3:
+			ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
+						SCU_FUN_PIN_UART3_RXD |
+						SCU_FUN_PIN_UART3_TXD |
+						SCU_FUN_PIN_UART3_NRTS |
+						SCU_FUN_PIN_UART3_NDTR |
+						SCU_FUN_PIN_UART3_NRI |
+						SCU_FUN_PIN_UART3_NDSR |
+						SCU_FUN_PIN_UART3_NDCD |
+						SCU_FUN_PIN_UART3_NCTS, 
+				AST_SCU_FUN_PIN_CTRL1); 
+			break;
+		case 4:
+			ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
+						SCU_FUN_PIN_UART4_RXD |
+						SCU_FUN_PIN_UART4_TXD |
+						SCU_FUN_PIN_UART4_NRTS |
+						SCU_FUN_PIN_UART4_NDTR |
+						SCU_FUN_PIN_UART4_NRI |
+						SCU_FUN_PIN_UART4_NDSR |
+						SCU_FUN_PIN_UART4_NDCD |
+						SCU_FUN_PIN_UART4_NCTS, 
+				AST_SCU_FUN_PIN_CTRL1); 			
+			break;
+	}
+
+
+}
+
+extern void
+ast_scu_multi_func_video()
+{
+#if defined(CONFIG_ARCH_2100) || defined(CONFIG_ARCH_2200)
+	ast_scu_write(ast_scu_read(AST_SCU_MULTI_FUNC_2) |
+				MULTI_FUNC_VIDEO_RGB18 |
+				MULTI_FUNC_VIDEO_SINGLE_EDGE, 
+		AST_SCU_MULTI_FUNC_2); 
+#elif defined(CONFIG_ARCH_1100) || defined(CONFIG_ARCH_2050)
+	ast_scu_write(ast_scu_read(AST_SCU_MULTI_FUNC_2) |
+				MULTI_FUNC_VIDEO_RGB18 |
+				MULTI_FUNC_VIDEO_SINGLE_EDGE, 
+		AST_SCU_MULTI_FUNC_2); 
+#else
+
+#endif
+}
+
+extern void
+ast_scu_multi_func_eth(u8 num)
+{
+	switch(num) {
+		case 0:
+			if(ast_scu_read(AST_SCU_HW_STRAP1) && SCU_HW_STRAP_MAC0_RGMII) {
+				SCUMSG("MAC0 : RGMII \n");
+				ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) | 
+							SCU_FUN_PIN_MAC0_PHY_LINK, 
+					AST_SCU_FUN_PIN_CTRL1); 
+			} else {
+				SCUMSG("MAC0 : RMII/NCSI \n");			
+				ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) &
+							~SCU_FUN_PIN_MAC0_PHY_LINK, 
+					AST_SCU_FUN_PIN_CTRL1); 
+			}
+
+			ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) | 
+						SCU_FUN_PIN_MAC0_MDIO |
+						SCU_FUN_PIN_MAC0_MDC, 
+				AST_SCU_FUN_PIN_CTRL3); 
+			
+			break;
+		case 1:
+			if(ast_scu_read(AST_SCU_HW_STRAP1) && SCU_HW_STRAP_MAC1_RGMII) {
+				SCUMSG("MAC1 : RGMII \n");
+				ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) | 
+							SCU_FUN_PIN_MAC1_PHY_LINK, 
+					AST_SCU_FUN_PIN_CTRL1); 
+			} else {
+				SCUMSG("MAC1 : RMII/NCSI \n");
+				ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) & 
+						~SCU_FUN_PIN_MAC1_PHY_LINK, 
+					AST_SCU_FUN_PIN_CTRL1); 
+			}
+			
+			ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | 
+						SCU_FUC_PIN_MAC1_MDIO,
+				AST_SCU_FUN_PIN_CTRL5); 
+
+			break;
+	}
+}
+
+extern void
+ast_scu_multi_func_nand(void)
+{
+	//enable NAND flash multipin FLBUSY and FLWP
+	ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) | 
+				SCU_FUN_PIN_NAND_FLBUSY | SCU_FUN_PIN_NAND_FLWP, 
+		AST_SCU_FUN_PIN_CTRL2); 
+
+}
+
+extern void
+ast_scu_multi_func_nor(void)
+{
+	//Address 
+	//ROMA2~17
+	ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL8) | 
+				SCU_FUN_PIN_ROMA2 | SCU_FUN_PIN_ROMA3 |
+				SCU_FUN_PIN_ROMA4 | SCU_FUN_PIN_ROMA5 |
+				SCU_FUN_PIN_ROMA6 | SCU_FUN_PIN_ROMA7 |
+				SCU_FUN_PIN_ROMA8 | SCU_FUN_PIN_ROMA9 |
+				SCU_FUN_PIN_ROMA10 | SCU_FUN_PIN_ROMA11 |
+				SCU_FUN_PIN_ROMA12 | SCU_FUN_PIN_ROMA13 |
+				SCU_FUN_PIN_ROMA14 | SCU_FUN_PIN_ROMA15 |
+				SCU_FUN_PIN_ROMA16 | SCU_FUN_PIN_ROMA17, 
+		AST_SCU_FUN_PIN_CTRL8);
+
+	//ROMA18~21
+	ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL9) | 
+				SCU_FUN_PIN_ROMA18 | SCU_FUN_PIN_ROMA19 |
+				SCU_FUN_PIN_ROMA20 | SCU_FUN_PIN_ROMA21, 
+		AST_SCU_FUN_PIN_CTRL9);	
+	
+	//ROMA22,23
+	ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL4) | SCU_FUN_PIN_ROMA22 | SCU_FUN_PIN_ROMA23, 
+		AST_SCU_FUN_PIN_CTRL4);
+	
+	//ROMA24,25
+	ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) | SCU_FUN_PIN_ROMA24 | SCU_FUN_PIN_ROMA25, 
+		AST_SCU_FUN_PIN_CTRL3);
+
+	//SCU94 [1] = 0
+ 	ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL6) & SCU_VIDEO_OUT_MASK, 
+		AST_SCU_FUN_PIN_CTRL6);
+
+	
+	//data
+	//ROMD 4~7 //ROMWE#, OE#
+	ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL4) | 
+			SCU_FUN_PIN_ROMOE | SCU_FUN_PIN_ROMWE |
+			SCU_FUN_PIN_ROMD4 | SCU_FUN_PIN_ROMD5 |
+			SCU_FUN_PIN_ROMD6 | SCU_FUN_PIN_ROMD7,
+			AST_SCU_FUN_PIN_CTRL4);
+	
+	//ROMD 8~15
+	ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | 
+			SCU_FUC_PIN_ROM_16BIT, 
+		AST_SCU_FUN_PIN_CTRL5);
+
+}
+
+extern void
+ast_scu_multi_func_romcs(u8 num)
+{
+	ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) | 
+			SCU_FUN_PIN_ROMCS(num), 
+		AST_SCU_FUN_PIN_CTRL3);
+}
+
+extern void
+ast_scu_multi_func_i2c(void)
+{
+	//TODO check ... //In AST2400 Due to share pin with SD , please not enable I2C 10 ~14 
+	// AST 2400 have 14 , AST 2300 9 ...
+#ifdef CONFIG_MMC_AST
+	ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | 
+			SCU_FUC_PIN_I2C3 | 
+			SCU_FUC_PIN_I2C4 | 
+			SCU_FUC_PIN_I2C5 | 
+			SCU_FUC_PIN_I2C6 | 
+			SCU_FUC_PIN_I2C7 | 
+			SCU_FUC_PIN_I2C8 | 
+			SCU_FUC_PIN_I2C9, 
+		AST_SCU_FUN_PIN_CTRL5);
+#else
+	ast_scu_write((ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | 
+			SCU_FUC_PIN_I2C3 | 
+			SCU_FUC_PIN_I2C4 | 
+			SCU_FUC_PIN_I2C5 | 
+			SCU_FUC_PIN_I2C6 | 
+			SCU_FUC_PIN_I2C7 | 
+			SCU_FUC_PIN_I2C8 | 
+			SCU_FUC_PIN_I2C9 | 
+			SCU_FUC_PIN_I2C10 | 
+			SCU_FUC_PIN_I2C11 | 
+			SCU_FUC_PIN_I2C12 | 
+			SCU_FUC_PIN_I2C13 | 
+			SCU_FUC_PIN_I2C14) &
+			~(SCU_FUC_PIN_SD1 | SCU_FUC_PIN_SD2), 
+		AST_SCU_FUN_PIN_CTRL5);
+#endif
+}	
+
+EXPORT_SYMBOL(ast_scu_multi_func_i2c);
+
+extern void
+ast_scu_multi_func_pwm_tacho(void)
+{
+	//TODO check
+	u32 sts = ast_scu_read(AST_SCU_FUN_PIN_CTRL3) &~0xcfffff;
+	ast_scu_write(sts | 0xc000ff, AST_SCU_FUN_PIN_CTRL3);
+}	
+
+EXPORT_SYMBOL(ast_scu_multi_func_pwm_tacho);
+
+//0 : hub mode , 1: usb host mode
+extern void
+ast_scu_multi_func_usb20_host_hub(u8 mode)
+{
+	if(mode)
+		ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB20_HOST, 
+					AST_SCU_FUN_PIN_CTRL5);
+	else
+		ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB20_HOST, 
+					AST_SCU_FUN_PIN_CTRL5);
+}	
+
+EXPORT_SYMBOL(ast_scu_multi_func_usb20_host_hub);
+
+//0 : gpioQ6,7 mode , 1: usb1.1 host port 4 mode
+extern void
+ast_scu_multi_func_usb11_host_port4(u8 mode)
+{
+	if(mode)
+		ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB11_PORT4, 
+					AST_SCU_FUN_PIN_CTRL5);
+	else
+		ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB11_PORT4, 
+					AST_SCU_FUN_PIN_CTRL5);
+}	
+
+EXPORT_SYMBOL(ast_scu_multi_func_usb11_host_port4);
+
+//0 : USB 1.1 HID mode , 1: usb1.1 host port 2 mode
+extern void
+ast_scu_multi_func_usb11_host_port2(u8 mode)
+{
+	if(mode)
+		ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB11_PORT2, 
+					AST_SCU_FUN_PIN_CTRL5);
+	else
+		ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB11_PORT2, 
+					AST_SCU_FUN_PIN_CTRL5);
+}	
+
+EXPORT_SYMBOL(ast_scu_multi_func_usb11_host_port2);
+
+//0 : 1: SD1 function 
+extern void
+ast_scu_multi_func_sdhc_slot1(u8 mode)
+{
+	if(mode)
+		ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_SD1, 
+					AST_SCU_FUN_PIN_CTRL5);
+	else
+		ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_SD1, 
+					AST_SCU_FUN_PIN_CTRL5);
+}	
+
+EXPORT_SYMBOL(ast_scu_multi_func_sdhc_slot1);
+
+extern void
+ast_scu_multi_func_sdhc_slot2(u8 mode)
+{
+	if(mode)
+		ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_SD2, 
+					AST_SCU_FUN_PIN_CTRL5);
+	else
+		ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_SD2, 
+					AST_SCU_FUN_PIN_CTRL5);
+
+}	
+
+EXPORT_SYMBOL(ast_scu_multi_func_sdhc_slot2);
+
+extern void
+ast_scu_multi_func_crt(void)
+{
+	/* multi-pin for DVO */
+
+	//Digital vodeo input function pins : 00 disable, 10 24bits mode 888,
+	ast_scu_write((ast_scu_read(AST_SCU_FUN_PIN_CTRL5) &
+			~SCU_FUC_PIN_DIGI_V_OUT_MASK) | 
+			SCU_FUC_PIN_DIGI_V_OUT(VIDEO_24BITS),AST_SCU_FUN_PIN_CTRL5);
+
+	//VPI input
+#if 0	
+	ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
+			SCU_FUN_PIN_VPIB9 | SCU_FUN_PIN_VPIB8 |
+			SCU_FUN_PIN_VPIB7 | SCU_FUN_PIN_VPIB6 |
+			SCU_FUN_PIN_VPIB5 | SCU_FUN_PIN_VPIB4 |
+			SCU_FUN_PIN_VPIB3 | SCU_FUN_PIN_VPIB2 |
+			SCU_FUN_PIN_VPIB1 | SCU_FUN_PIN_VPIB0 |
+			SCU_FUN_PIN_VPICLK | SCU_FUN_PIN_VPIVS |
+			SCU_FUN_PIN_VPIHS | SCU_FUN_PIN_VPIODD |
+			SCU_FUN_PIN_VPIDE ,AST_SCU_FUN_PIN_CTRL2);
+
+	ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
+			SCU_FUN_PIN_VPIR9 | SCU_FUN_PIN_VPIR8 |
+			SCU_FUN_PIN_VPIR7 | SCU_FUN_PIN_VPIR6 |	
+			SCU_FUN_PIN_VPIR5 | SCU_FUN_PIN_VPIR4 |
+			SCU_FUN_PIN_VPIR3 | SCU_FUN_PIN_VPIR2 |
+			SCU_FUN_PIN_VPIR1 | SCU_FUN_PIN_VPIR0 |
+			SCU_FUN_PIN_VPIG9 | SCU_FUN_PIN_VPIG8 |	
+			SCU_FUN_PIN_VPIG7 | SCU_FUN_PIN_VPIG6 |
+			SCU_FUN_PIN_VPIG5 | SCU_FUN_PIN_VPIG4 |
+			SCU_FUN_PIN_VPIG3 | SCU_FUN_PIN_VPIG2 |
+			SCU_FUN_PIN_VPIG1 | SCU_FUN_PIN_VPIG0 ,AST_SCU_FUN_PIN_CTRL3);
+#endif
+}
+
+EXPORT_SYMBOL(ast_scu_multi_func_crt);
+//***********************************Information ***********************************
+extern u32
+ast_scu_revision_id(void)
+{
+	int i;
+	u32 rev_id = ast_scu_read(AST_SCU_REVISION_ID);
+	for(i=0;i<ARRAY_SIZE(soc_map_table);i++) {
+		if(rev_id == soc_map_table[i].rev_id)
+			break;
+	}
+	if(i == ARRAY_SIZE(soc_map_table))
+		SCUMSG("UnKnow-SOC : %x \n",rev_id);
+	else
+		SCUMSG("SOC : %4s \n",soc_map_table[i].name);
+	
+	return rev_id;
+}	
+
+EXPORT_SYMBOL(ast_scu_revision_id);
+
+/*
+* D[15:11] in 0x1E6E2040 is NCSI scratch from U-Boot. D[15:14] = MAC1, D[13:12] = MAC2
+* The meanings of the 2 bits are:
+* 00(0): Dedicated PHY
+* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
+* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
+* 11: Reserved
+*/
+
+extern u32
+ast_scu_get_phy_config(u8 mac_num)
+{
+	u32 scatch = ast_scu_read(AST_SCU_SOC_SCRATCH0);
+
+	switch(mac_num) {
+		case 0:
+			return (SCU_MAC0_GET_PHY_MODE(scatch));
+			break;
+		case 1:
+			return (SCU_MAC1_GET_PHY_MODE(scatch));
+			break;
+		default:
+			SCUMSG("error mac number \n");
+			break;
+	}
+	return -1;
+}
+EXPORT_SYMBOL(ast_scu_get_phy_config);
+
+extern u32
+ast_scu_get_phy_interface(u8 mac_num)
+{
+	u32 trap1 = ast_scu_read(AST_SCU_HW_STRAP1);
+
+	switch(mac_num) {
+		case 0:
+			if(SCU_HW_STRAP_MAC0_RGMII & trap1)
+				return 1;
+			else
+				return 0;
+			break;
+		case 1:
+			if(SCU_HW_STRAP_MAC1_RGMII & trap1)
+				return 1;
+			else
+				return 0;
+			break;
+		default:
+			SCUMSG("error mac number \n");
+			break;
+	}
+	return -1;
+}
+EXPORT_SYMBOL(ast_scu_get_phy_interface);
+
+extern void
+ast_scu_set_vga_display(u8 enable)
+{
+	if(enable)
+		printk("111111");
+}
+
+EXPORT_SYMBOL(ast_scu_set_vga_display);
+
+extern u32
+ast_scu_get_vga_memsize(void)
+{
+	u32 size=0;
+
+	switch(SCU_HW_STRAP_VGA_SIZE_GET(ast_scu_read(AST_SCU_HW_STRAP1))) {
+		case 0:
+			size = 8*1024*1024;
+			break;
+		case 1:
+			size = 16*1024*1024;
+			break;
+		case 2:
+			size = 32*1024*1024;
+			break;
+		case 3:
+			size = 64*1024*1024;
+			break;
+		default:
+			SCUMSG("error vga size \n");
+			break;
+	}
+	return size;
+}
+
+EXPORT_SYMBOL(ast_scu_get_vga_memsize);
+
+extern void
+ast_scu_get_who_init_dram(void)
+{
+	switch(SCU_VGA_DRAM_INIT_MASK(ast_scu_read(AST_SCU_VGA0))) {
+		case 0:
+			SCUMSG("VBIOS init \n");
+			break;
+		case 1:
+			SCUMSG("SOC init \n");
+			break;
+		default:
+			SCUMSG("error vga size \n");
+			break;
+	}
+}
diff --git a/arch/arm/plat-aspeed/ast-sdmc.c b/arch/arm/plat-aspeed/ast-sdmc.c
new file mode 100644
index 0000000..238cf79
--- /dev/null
+++ b/arch/arm/plat-aspeed/ast-sdmc.c
@@ -0,0 +1,100 @@
+/********************************************************************************
+* File Name     : arch/arm/mach-aspeed/ast-sdmc.c 
+* Author         : Ryan Chen
+* Description   : AST SDRAM Memory Ctrl
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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 
+
+
+*   History      : 
+*    1. 2013/03/15 Ryan Chen Create
+* 
+********************************************************************************/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#include <mach/platform.h>
+#include <mach/hardware.h>
+
+#include <plat/ast-sdmc.h>
+#include <plat/regs-sdmc.h>
+
+//#define AST_SDMC_LOCK
+//#define AST_SDMC_DEBUG
+
+#ifdef AST_SDMC_DEBUG
+#define SDMCDBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
+#else
+#define SDMCDBUG(fmt, args...)
+#endif
+
+#define SDMCMSG(fmt, args...) printk(fmt, ## args)
+
+static u32 ast_sdmc_base = IO_ADDRESS(AST_SDMC_BASE);
+
+static inline u32 
+ast_sdmc_read(u32 reg)
+{
+	u32 val;
+		
+	val = readl(ast_sdmc_base + reg);
+	
+	SDMCDBUG("ast_sdmc_read : reg = 0x%08x, val = 0x%08x\n", reg, val);
+	
+	return val;
+}
+
+static inline void
+ast_sdmc_write(u32 val, u32 reg) 
+{
+	SDMCDBUG("ast_sdmc_write : reg = 0x%08x, val = 0x%08x\n", reg, val);
+#ifdef CONFIG_AST_SDMC_LOCK
+	//unlock 
+	writel(SDMC_PROTECT_UNLOCK, ast_sdmc_base);
+	writel(val, ast_sdmc_base + reg);
+	//lock
+	writel(0xaa,ast_sdmc_base);	
+#else
+	writel(SDMC_PROTECT_UNLOCK, ast_sdmc_base);
+
+	writel(val, ast_sdmc_base + reg);
+#endif
+}
+
+//***********************************Information ***********************************
+extern u32
+ast_sdmc_get_mem_size(void)
+{
+	u32 size=0;
+	switch(SDMC_CONFIG_MEM_GET(ast_sdmc_read(AST_SDMC_CONFIG))) {
+		case 0:
+			size = 64*1024*1024;
+			break;
+		case 1:
+			size = 128*1024*1024;
+			break;
+		case 2:
+			size = 256*1024*1024;
+			break;
+		case 3:
+			size = 512*1024*1024;
+			break;
+			
+		default:
+			SDMCMSG("error ddr size \n");
+			break;
+	}
+	return size;
+}
+
diff --git a/arch/arm/plat-aspeed/ast1070-scu.c b/arch/arm/plat-aspeed/ast1070-scu.c
new file mode 100644
index 0000000..4ad12c7
--- /dev/null
+++ b/arch/arm/plat-aspeed/ast1070-scu.c
@@ -0,0 +1,178 @@
+/********************************************************************************
+* File Name     : arch/arm/mach-aspeed/ast1070-scu.c 
+* Author         : Ryan Chen
+* Description   : AST1070 SCU 
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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 
+
+*   History      : 
+*    1. 2013/05/15 Ryan Chen Create
+* 
+********************************************************************************/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#include <mach/platform.h>
+#include <asm/io.h>
+
+#include <mach/hardware.h>
+
+#include <plat/ast1070-scu.h>
+#include <plat/regs-ast1070-scu.h>
+
+#define CONFIG_AST1070_SCU_LOCK
+//#define AST1070_SCU_DEBUG
+
+#ifdef AST1070_SCU_DEBUG
+#define SCUDBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
+#else
+#define SCUDBUG(fmt, args...)
+#endif
+
+#define SCUMSG(fmt, args...) printk(fmt, ## args)
+
+static u32 ast1070_scu_base = IO_ADDRESS2(AST_C0_SCU_BASE);
+
+static inline u32 
+ast1070_scu_read(u8 node, u32 reg)
+{
+	u32 val;
+		
+	val = readl(ast1070_scu_base + (node * 0x10000) + reg);
+	
+	SCUDBUG("ast1070_scu_read : reg = 0x%08x, val = 0x%08x\n", reg, val);
+	
+	return val;
+}
+
+static inline void
+ast1070_scu_write(u8 node, u32 val, u32 reg) 
+{
+	SCUDBUG("ast1070_scu_write : reg = 0x%08x, val = 0x%08x\n", reg, val);
+#ifdef CONFIG_AST1070_SCU_LOCK
+	//unlock 
+	writel(AST1070_SCU_PROTECT_UNLOCK, ast1070_scu_base  + (node * 0x10000));
+	writel(val, ast1070_scu_base + (node * 0x10000) + reg);
+	//lock
+//	writel(0xaa,ast1070_scu_base + (node * 0x10000));	
+#else
+	writel(val, ast1070_scu_base  + (node * 0x10000) + reg);
+#endif
+}
+
+extern void
+ast1070_scu_init_uart(u8 node)
+{
+	//SCU UART Reset
+	ast1070_scu_write(node, ast1070_scu_read(node, AST1070_SCU_RESET) & 
+			~(SCU_RESET_N1_UART | SCU_RESET_N2_UART | 
+			SCU_RESET_N3_UART | SCU_RESET_N4_UART), 
+			AST1070_SCU_RESET);
+}
+
+EXPORT_SYMBOL(ast1070_scu_init_uart);
+
+extern void
+ast1070_scu_init_i2c(u8 node)
+{
+	//SCU I2C Reset 
+	ast1070_scu_write(node, ast1070_scu_read(node, AST1070_SCU_RESET) & ~SCU_RESET_I2C, AST1070_SCU_RESET);
+}
+
+EXPORT_SYMBOL(ast1070_scu_init_i2c);
+
+extern void
+ast1070_dma_init(u8 node)
+{
+	u32 val =0;
+
+	//let the uart_dma engine leave the reset state
+	ast1070_scu_write(node, ast1070_scu_read(node, AST1070_SCU_RESET) & ~SCU_RESET_DMA, AST1070_SCU_RESET);
+
+	val = ast1070_scu_read(node, AST1070_SCU_MISC_CTRL) & ~SCU_DMA_M_S_MASK;
+
+	if(ast1070_scu_read(node, AST1070_SCU_TRAP) & TRAP_MULTI_MASTER) {
+		//AST1070 multi Initial DMA
+		if(ast1070_scu_read(node, AST1070_SCU_TRAP) & TRAP_DEVICE_SLAVE)
+			ast1070_scu_write(node, val | SCU_DMA_SLAVE_EN, AST1070_SCU_MISC_CTRL);			
+		else
+			//Enable DMA master
+			ast1070_scu_write(node, val | SCU_DMA_MASTER_EN, AST1070_SCU_MISC_CTRL);
+
+	} else {
+		//AST1070 single 
+		ast1070_scu_write(node, val, AST1070_SCU_MISC_CTRL);
+	}
+}
+EXPORT_SYMBOL(ast1070_dma_init);
+
+
+extern void
+ast1070_scu_init_lpc(void)
+{
+
+}
+
+EXPORT_SYMBOL(ast1070_scu_init_lpc);
+
+//***********************************Multi-function pin control***********************************
+
+extern void
+ast1070_multi_func_uart(u8 node, u8 uart)
+{
+	ast1070_scu_write(node, (ast1070_scu_read(node, AST1070_SCU_UART_MUX) &
+				~UART_MUX_MASK(uart)) |
+				SET_UART_IO_PAD(uart,PAD_FROM_BMC) | 
+				SET_NODE_UART_CTRL(uart, NODE_UART_FROM_NONE) | 
+				SET_BMC_UART_CTRL(uart, BMC_UART_FROM_PAD1),
+				AST1070_SCU_UART_MUX); 
+
+}
+
+EXPORT_SYMBOL(ast1070_multi_func_uart);
+
+
+//***********************************CLK control***********************************
+
+
+//***********************************CLK Information***********************************
+extern u32
+ast1070_get_clk_source(void)
+{
+
+}
+EXPORT_SYMBOL(ast1070_get_clk_source);
+
+//***********************************Information ***********************************
+extern void
+ast1070_scu_revision_id(u8 node)
+{
+	u32 rev_id;
+
+#if 0	
+	if(gpio_get_value(PIN_GPIOI1))
+		printk("Use LPC+ Bus Access \n");
+	else
+		printk("Use LPC Bus Access \n");		
+#endif
+
+	rev_id = ast1070_scu_read(node, AST1070_SCU_CHIP_ID);
+	if (ast1070_scu_read(node, AST1070_SCU_TRAP) & TRAP_LPC_PLUS_MODE) {
+		printk("LPC+ : ");
+	} else
+		printk("LPC : ");
+
+	printk("AST1070-[C%d] rev_id[%x] \n",node,rev_id);
+}	
+
+EXPORT_SYMBOL(ast1070_scu_revision_id);
diff --git a/arch/arm/plat-aspeed/ast1070-uart-dma.c b/arch/arm/plat-aspeed/ast1070-uart-dma.c
new file mode 100644
index 0000000..9da401e
--- /dev/null
+++ b/arch/arm/plat-aspeed/ast1070-uart-dma.c
@@ -0,0 +1,572 @@
+/*
+ *  ast1070-uart-dma.c
+ *
+ *  UART DMA for the AST1070 UART access.
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *  History:
+ *    2012.05.26: Initial version [Ryan Chen]
+ */
+
+#include <linux/sysdev.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/ast-uart-dma.h>
+#include <plat/regs-uart-dma.h>
+
+//#define AST_UART_DMA_DEBUG
+
+#ifdef AST_UART_DMA_DEBUG
+#define DMADUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
+#else
+#define DMADUG(fmt, args...)
+#endif
+
+//#define AST1070_FPGA			1
+
+struct ast1070_dma uart_dma[CONFIG_AST1070_NR];
+
+static inline void
+ast1070_uart_dma_write(struct ast1070_dma *dma, u32 val, u32 reg)
+{
+	//printk("uart dma write : val: %x , reg : %x \n",val,reg);	
+	writel(val, dma->reg_base+ reg);
+}
+
+static inline u32
+ast1070_uart_dma_read(struct ast1070_dma *dma, u32 reg)
+{
+#if 0
+	u32 val = readl(i2c_dev->reg_base + reg);
+	printk("R : reg %x , val: %x \n",reg, val);
+	return val;
+#else	
+	return readl(dma->reg_base + reg);
+#endif
+}
+
+/* *****************************************************************************/
+int ast_uart_rx_dma_enqueue(u8 node, u8 ch, dma_addr_t rx_buff, u16 len)
+{
+	unsigned long flags;
+	struct ast1070_dma *dma = &uart_dma[node];
+	struct ast1070_dma_ch *dma_ch = &(dma->dma_rx_ch[ch]);
+	struct uart_dma_desc *rx_desc = dma_ch->desc;
+
+	if(len > 4096)
+		printk("ERROR !!!  Please Check ...\n");
+	
+	local_irq_save(flags);
+
+	//fill to rx desc -->
+	rx_desc->desc0 = DESC0_END | DESC0_INT_EN | DESC0_HW_OWN;
+	rx_desc->desc1 = DESC1_LEN(len);
+	rx_desc->desc2 = rx_buff;
+	rx_desc->desc3 = 0;
+
+	DMADUG("[c%d]: ch = %d, rx buff = %x, len = %d \n",node, ch, rx_buff, len);
+
+	//fill in tx descriptor base register
+	DMADUG("desc_addr : %x, reg offset %x \n",dma_ch->desc_dma_addr, dma_ch->desc_offset);	
+	ast1070_uart_dma_write(dma, dma_ch->desc_dma_addr, dma_ch->desc_offset);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(ast_uart_rx_dma_enqueue);
+
+int ast_uart_tx_dma_enqueue(u8 node, u8 ch, dma_addr_t tx_buff, u16 len)
+{
+	unsigned long flags;
+	struct ast1070_dma *dma = &uart_dma[node];
+	struct ast1070_dma_ch *dma_ch = &(dma->dma_tx_ch[ch]);
+	struct uart_dma_desc *tx_desc = dma_ch->desc;
+
+	DMADUG("[c%d]: ch = %d, tx buff = %x, len = %d \n",node, ch, tx_buff, len);
+
+	local_irq_save(flags);
+
+	//fill to rx desc -->
+	tx_desc->desc0 = DESC0_END | DESC0_INT_EN | DESC0_HW_OWN;
+	tx_desc->desc1 = DESC1_LEN(len);
+	tx_desc->desc2 = tx_buff;
+	tx_desc->desc3 = 0;
+
+//	DMADUG("desc vir = %x, tx desc = %x, %x, %x, %x  ===\n",tx_desc, tx_desc->desc0 ,tx_desc->desc1,tx_desc->desc2,tx_desc->desc3);
+	//fill in tx descriptor base register
+	DMADUG("desc_addr : %x, in offset %x \n",dma_ch->desc_dma_addr, dma_ch->desc_offset);
+	ast1070_uart_dma_write(dma, dma_ch->desc_dma_addr, dma_ch->desc_offset);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(ast_uart_tx_dma_enqueue);
+
+int ast_uart_rx_dma_ctrl(u8 node, u8 ch, enum ast_uart_chan_op op)
+{
+	unsigned long flags;
+	struct ast1070_dma *dma = &uart_dma[node];
+	struct ast1070_dma_ch *dma_ch = &(dma->dma_rx_ch[ch]);
+	DMADUG("[c%d]: ch = %d \n",node, ch);
+
+	local_irq_save(flags);
+
+	switch (op) {
+		case AST_UART_DMAOP_TRIGGER:
+			//trigger 
+			DMADUG("Trigger \n");
+			dma_ch->enable = 1;	
+//			ast1070_uart_dma_write(dma, DMA_ENABLE, dma_ch->ctrl_offset);
+			ast1070_uart_dma_write(dma, DMA_TRIGGER | DMA_ENABLE, dma_ch->ctrl_offset);
+			break;
+
+		case AST_UART_DMAOP_STOP:
+			//disable engine 
+			DMADUG("Stop \n");			
+			dma_ch->enable = 0;
+			ast1070_uart_dma_write(dma, 0, dma_ch->ctrl_offset);
+			break;
+	}
+
+
+	return 0;	
+}
+EXPORT_SYMBOL(ast_uart_rx_dma_ctrl);
+
+int ast_uart_tx_dma_ctrl(u8 node, u8 ch, enum ast_uart_chan_op op)
+{
+	unsigned long flags;
+	struct ast1070_dma *dma = &uart_dma[node];
+	struct ast1070_dma_ch *dma_ch = &(dma->dma_tx_ch[ch]);
+	DMADUG("TX DMA CTRL [c%d]: ch = %d \n",node, ch);
+
+	local_irq_save(flags);
+
+	switch (op) {
+		case AST_UART_DMAOP_TRIGGER:
+			//trigger 
+			DMADUG("Trigger \n");			
+			ast1070_uart_dma_write(dma, DMA_ENABLE, dma_ch->ctrl_offset);
+			ast1070_uart_dma_write(dma, DMA_TRIGGER | DMA_ENABLE, dma_ch->ctrl_offset);
+			break;
+
+		case AST_UART_DMAOP_STOP:
+			//disable engine 
+			DMADUG("STOP \n");			
+			ast1070_uart_dma_write(dma, 0, dma_ch->ctrl_offset);
+			break;
+	}
+
+
+	return 0;	
+}
+EXPORT_SYMBOL(ast_uart_tx_dma_ctrl);
+
+int ast_uart_tx_dma_request(u8 node, u8 ch, ast_uart_dma_cbfn_t rtn, void *id)
+{
+	unsigned long flags;
+	struct ast1070_dma *dma = &uart_dma[node];
+	struct ast1070_dma_ch *dma_ch = &(dma->dma_tx_ch[ch]);
+
+	DMADUG("TX DMA REQUEST [c%d]: ch = %d \n",node, ch);
+
+	local_irq_save(flags);
+
+	if (dma_ch->enable) {
+		local_irq_restore(flags);
+		return -EBUSY;
+	}
+
+	dma_ch->priv = id;
+	dma_ch->enable = 1;
+	dma_ch->callback_fn = rtn;
+	//DMA IRQ En
+	ast1070_uart_dma_write(dma, 
+				ast1070_uart_dma_read(dma, UART_DMA_IER) |
+				(1 << ch)
+				, UART_DMA_IER);
+
+	//enable engine 
+//	ast1070_uart_dma_write(dma, DMA_ENABLE, dma_ch->ctrl_offset);
+	local_irq_restore(flags);
+
+	return 0;
+
+}
+
+EXPORT_SYMBOL(ast_uart_tx_dma_request);
+
+int ast_uart_rx_dma_request(u8 node, u8 ch, ast_uart_dma_cbfn_t rtn, void *id)
+{
+	unsigned long flags;
+	struct ast1070_dma *dma = &uart_dma[node];
+	struct ast1070_dma_ch *dma_ch = &(dma->dma_rx_ch[ch]);
+
+	DMADUG("RX DMA REQUEST [c%d] : ch = %d \n",node, ch);
+
+	local_irq_save(flags);
+
+	if (dma->dma_rx_ch[ch].enable) {
+		local_irq_restore(flags);
+		return -EBUSY;
+	}
+	dma_ch->priv = id;	
+//	dma_ch->enable = 1;
+	dma_ch->callback_fn = rtn;
+//	dma_ch->name
+	//DMA IRQ En
+	ast1070_uart_dma_write(dma, 
+				ast1070_uart_dma_read(dma, UART_DMA_IER) |
+				(1 << (4+ch))
+				, UART_DMA_IER);
+
+	//enable engine 
+//	ast1070_uart_dma_write(dma, DMA_ENABLE, dma_ch->ctrl_offset);
+	local_irq_restore(flags);
+
+	return 0;
+
+}
+
+EXPORT_SYMBOL(ast_uart_rx_dma_request);
+/* *****************************************************************************/
+static inline void ast_dma_bufffdone(struct ast1070_dma_ch	 *dma_ch)
+{
+	////TODO desc -- remove ......
+	//workaround : Issue RX dma can;t be stoped , close open close  
+	if(dma_ch->enable == 0) {
+//		printk("workaround \n");
+		return;
+	}
+		
+//	u32 sts = ast1070_uart_dma_read(dma, dma_ch->ctrl_offset);	
+	DMADUG("dma dwn : ch[%d] : %s ,len : %d \n", dma_ch->ch_no, dma_ch->direction ? "tx" : "rx", DESC3_GET_LEN(dma_ch->desc->desc3));
+
+	DMADUG(" == desc = %x, %x, %x, %x  ===\n",dma_ch->desc->desc0,dma_ch->desc->desc1,dma_ch->desc->desc2,dma_ch->desc->desc3);
+
+
+	if(dma_ch->desc->desc0 & DESC0_HW_OWN) 
+		printk("ERROR ..... \n");
+	
+	if (dma_ch->callback_fn != NULL)
+		(dma_ch->callback_fn)(dma_ch, dma_ch->priv, DESC3_GET_LEN(dma_ch->desc->desc3));
+}
+
+
+static irqreturn_t 
+ast1070_c0_uart_dma_irq(int irq, void *dev_id)
+{
+//	struct ast1070_dma	*dma = dev_id;
+	int i;
+	struct ast1070_dma *dma = &uart_dma[0];	
+	u32 sts = ast1070_uart_dma_read(dma, UART_DMA_ISR);
+	DMADUG("C0 int -- > \n");
+	DMADUG("isr sts = %x\n", sts);
+
+	for(i = 0;i < 17 ; i++)
+		DMADUG("offset : %x , val %x \n",i*4, ast1070_uart_dma_read(dma, i*4));
+	
+	if (sts & UART_DMA3_RX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA3_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[3]));
+	} else if (sts & UART_DMA2_RX_INT) {		
+		ast1070_uart_dma_write(dma, UART_DMA2_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[2]));
+	} else if (sts & UART_DMA1_RX_INT) {		
+		ast1070_uart_dma_write(dma, UART_DMA1_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[1]));
+	} else if (sts & UART_DMA0_RX_INT) {		
+		ast1070_uart_dma_write(dma, UART_DMA0_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[0]));
+	} else if (sts & UART_DMA3_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA3_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[3]));
+	} else if (sts & UART_DMA2_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA2_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[2]));
+	} else if (sts & UART_DMA1_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA1_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[1]));
+	} else if (sts & UART_DMA0_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA0_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[0]));
+	} else {
+		printk("No body .. !!! \n");
+	}
+
+	return IRQ_HANDLED;
+}
+
+#if (CONFIG_AST1070_NR >=2)
+static irqreturn_t 
+ast1070_c1_uart_dma_irq(int irq, void *dev_id)
+{
+//	struct ast1070_dma	*dma = dev_id;
+	struct ast1070_dma *dma = &uart_dma[1];
+	u32 sts = ast1070_uart_dma_read(dma, UART_DMA_ISR);
+	DMADUG("C1 int -- > \n");
+
+//	DMADUG("isr sts = %x\n", sts);
+	if (sts & UART_DMA3_RX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA3_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[3]));
+	} else if (sts & UART_DMA2_RX_INT) {		
+		ast1070_uart_dma_write(dma, UART_DMA2_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[2]));
+	} else if (sts & UART_DMA1_RX_INT) {		
+		ast1070_uart_dma_write(dma, UART_DMA1_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[1]));
+	} else if (sts & UART_DMA0_RX_INT) {		
+		ast1070_uart_dma_write(dma, UART_DMA0_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[0]));
+	} else if (sts & UART_DMA3_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA3_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[3]));
+	} else if (sts & UART_DMA2_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA2_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[2]));
+	} else if (sts & UART_DMA1_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA1_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[1]));
+	} else if (sts & UART_DMA0_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA0_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[0]));
+	} else {
+		printk("No body .. !!! \n");
+	}
+
+	return IRQ_HANDLED;
+}
+#endif
+
+#if (CONFIG_AST1070_NR >=3)
+static irqreturn_t 
+ast1070_c2_uart_dma_irq(int irq, void *dev_id)
+{
+	struct ast1070_dma	*dma = dev_id;
+	u32 sts = ast1070_uart_dma_read(dma, UART_DMA_ISR);
+
+//	DMADUG("isr sts = %x\n", sts);
+	if (sts & UART_DMA3_RX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA3_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[3]));
+	} else if (sts & UART_DMA2_RX_INT) {		
+		ast1070_uart_dma_write(dma, UART_DMA2_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[2]));
+	} else if (sts & UART_DMA1_RX_INT) {		
+		ast1070_uart_dma_write(dma, UART_DMA1_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[1]));
+	} else if (sts & UART_DMA0_RX_INT) {		
+		ast1070_uart_dma_write(dma, UART_DMA0_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[0]));
+	} else if (sts & UART_DMA3_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA3_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[3]));
+	} else if (sts & UART_DMA2_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA2_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[2]));
+	} else if (sts & UART_DMA1_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA1_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[1]));
+	} else if (sts & UART_DMA0_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA0_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[0]));
+	} else {
+		printk("No body .. !!! \n");
+	}
+
+	return IRQ_HANDLED;
+}
+#endif
+
+#if (CONFIG_AST1070_NR >=4)
+static irqreturn_t 
+ast1070_c3_uart_dma_irq(int irq, void *dev_id)
+{
+	struct ast1070_dma	*dma = dev_id;
+	u32 sts = ast1070_uart_dma_read(dma, UART_DMA_ISR);
+
+//	DMADUG("isr sts = %x\n", sts);
+	if (sts & UART_DMA3_RX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA3_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[3]));
+	} else if (sts & UART_DMA2_RX_INT) {		
+		ast1070_uart_dma_write(dma, UART_DMA2_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[2]));
+	} else if (sts & UART_DMA1_RX_INT) {		
+		ast1070_uart_dma_write(dma, UART_DMA1_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[1]));
+	} else if (sts & UART_DMA0_RX_INT) {		
+		ast1070_uart_dma_write(dma, UART_DMA0_RX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_rx_ch[0]));
+	} else if (sts & UART_DMA3_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA3_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[3]));
+	} else if (sts & UART_DMA2_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA2_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[2]));
+	} else if (sts & UART_DMA1_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA1_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[1]));
+	} else if (sts & UART_DMA0_TX_INT) {
+		ast1070_uart_dma_write(dma, UART_DMA0_TX_INT, UART_DMA_ISR);
+		ast_dma_bufffdone(&(dma->dma_tx_ch[0]));
+	} else {
+		printk("No body .. !!! \n");
+	}
+
+	return IRQ_HANDLED;
+}
+#endif
+
+extern int
+ast1070_uart_dma_init(u8 node)
+{
+    int ret,i;
+	struct ast1070_dma *dma = &uart_dma[node];
+
+	DMADUG("ast1070 uart_dma_init [c%d]\n", node);
+
+	if(node == 0) {	
+		dma->reg_base = ioremap(AST_C0_UART_DMA_BASE, 0x100);
+#if (CONFIG_AST1070_NR >=2)		
+	} else if (node == 1) {
+		dma->reg_base = ioremap(AST_C1_UART_DMA_BASE, 0x100);
+#endif		
+#if (CONFIG_AST1070_NR >=3)		
+	} else if (node == 2) {
+		dma->reg_base = ioremap(AST_C2_UART_DMA_BASE, 0x100);
+#endif		
+#if (CONFIG_AST1070_NR >=4)		
+	} else if (node == 3) {
+		dma->reg_base = ioremap(AST_C3_UART_DMA_BASE, 0x100);
+#endif		
+	} else {
+		printk("node out of range !! \n");
+		return 1;
+	}
+	
+	if (!dma->reg_base) {
+			printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
+			return -ENXIO;
+	}
+
+	ast1070_uart_dma_write(dma, 0xff, UART_DMA_ISR);
+	ast1070_uart_dma_write(dma, 0, UART_DMA_IER);
+
+	for(i=0;i<4;i++) {
+		//TX ------------------------
+		dma->dma_tx_ch[i].enable = 0;
+		dma->dma_tx_ch[i].ch_no = i;
+		dma->dma_tx_ch[i].direction = 1;
+		//tx descriptor allocation
+		dma->dma_tx_ch[i].desc = dma_alloc_coherent(NULL, sizeof(struct uart_dma_desc), &(dma->dma_tx_ch[i].desc_dma_addr), GFP_KERNEL);
+		if (dma->dma_tx_ch[i].desc == NULL) {
+			DMADUG("Can't allocate tx descriptor\n");
+			return 0;
+		}
+		memset(dma->dma_tx_ch[i].desc, 0, sizeof(struct uart_dma_desc));
+		DMADUG("tx_desc [%d] virt = %x, dma = %x\n", i, (u32)dma->dma_tx_ch[i].desc, dma->dma_tx_ch[i].desc_dma_addr);
+
+		ast1070_uart_dma_write(dma, 0, UART_DMA0_TX_CTRL + (i*8));
+		dma->dma_tx_ch[i].ctrl_offset = UART_DMA0_TX_CTRL + (i*8);
+		dma->dma_tx_ch[i].desc_offset = UART_DMA0_TX_DESCPT + (i*8);
+
+		//RX ------------------------
+		dma->dma_rx_ch[i].enable = 0;
+		dma->dma_rx_ch[i].ch_no = i;	
+		dma->dma_rx_ch[i].direction = 0;
+		//rx descriptor allocation
+		dma->dma_rx_ch[i].desc = dma_alloc_coherent(NULL, sizeof(struct uart_dma_desc), &(dma->dma_rx_ch[i].desc_dma_addr), GFP_KERNEL);
+		if (dma->dma_rx_ch[i].desc == NULL) {
+			DMADUG("Can't allocate tx descriptor\n");
+			return 0;
+		}
+		memset(dma->dma_rx_ch[i].desc, 0, sizeof(struct uart_dma_desc));
+		DMADUG("rx_desc [%d] virt = %x, dma = %x\n", i, (u32)dma->dma_rx_ch[i].desc, dma->dma_rx_ch[i].desc_dma_addr);
+		ast1070_uart_dma_write(dma, 0, UART_DMA0_RX_CTRL + (i*8));
+		dma->dma_rx_ch[i].ctrl_offset = UART_DMA0_RX_CTRL + (i*8);
+		dma->dma_rx_ch[i].desc_offset = UART_DMA0_RX_DESCPT + (i*8);
+	}
+
+	DMADUG("reg base = %x \n", (u32)dma->reg_base);
+
+	if(node == 0) {
+		for(i=0;i<4;i++) {
+			ret = request_irq(IRQ_C0_N1_UART_DMA + i, 
+									ast1070_c0_uart_dma_irq, IRQF_SHARED, 
+									"ast1070_n1_uart_dma", dma);
+			if (ret)
+				printk ("Unable to get UART DMA IRQ !!!!!!!!!!!!!!!!!!!!\n");
+		}
+#if (CONFIG_AST1070_NR >=2)
+	} else if (node == 1) {
+		for(i=0;i<4;i++) {
+			ret = request_irq(IRQ_C1_N1_UART_DMA + i, 
+									ast1070_c1_uart_dma_irq, IRQF_SHARED, 
+									"ast1070_n1_uart_dma", dma);
+			if (ret)
+				printk ("Unable to get UART DMA IRQ !!!!!!!!!!!!!!!!!!!!\n");
+		}
+#endif
+#if (CONFIG_AST1070_NR >=3)
+	} else if (node == 2) {
+		for(i=0;i<4;i++) {
+			ret = request_irq(IRQ_C2_N1_UART_DMA + i, 
+									ast1070_c2_uart_dma_irq, IRQF_SHARED, 
+									"ast1070_n1_uart_dma", dma);
+			if (ret)
+				printk ("Unable to get UART DMA IRQ !!!!!!!!!!!!!!!!!!!!\n");
+	}
+#endif
+#if (CONFIG_AST1070_NR >=4)
+	} else if (node == 3) {
+		for(i=0;i<4;i++) {
+			ret = request_irq(IRQ_C3_N1_UART_DMA + i, 
+									ast1070_c3_uart_dma_irq, IRQF_SHARED, 
+									"ast1070_n1_uart_dma", dma);
+			if (ret)
+				printk ("Unable to get UART DMA IRQ !!!!!!!!!!!!!!!!!!!!\n");
+		}
+#endif	
+	} else {
+		printk("ERROR !! \n");
+	}
+
+	//Limit : AST1070 4* SPI CLK < AST2400 HCLK
+
+#ifdef AST1070_FPGA
+	//Low SPI clk setting  == PCLK/8 , set 11
+	ast1070_uart_dma_write(dma, 
+					(ast1070_uart_dma_read(dma, UART_DMA_CTRL) & ~SPI_CLK_MASK) |
+					SPI_CLK_SET(0x3) |
+					DMA_RX_TIMEOUT(0xfff) |
+					TXDESC_AUTO_POLLING |
+					RXDESC_AUTO_POLLING
+					, UART_DMA_CTRL);
+#else
+	ast1070_uart_dma_write(dma, 
+					(ast1070_uart_dma_read(dma, UART_DMA_CTRL) & 
+					~DMA_BURST_MASK) |
+					DMA_RX_TIMEOUT(0xfff) |
+					TXDESC_AUTO_POLLING |
+					RXDESC_AUTO_POLLING
+					, UART_DMA_CTRL);
+#endif	
+
+    return 0;
+}                                                                              
+
+EXPORT_SYMBOL(ast1070_uart_dma_init);
diff --git a/arch/arm/plat-aspeed/ast1070_irq.c b/arch/arm/plat-aspeed/ast1070_irq.c
new file mode 100644
index 0000000..e859cd1
--- /dev/null
+++ b/arch/arm/plat-aspeed/ast1070_irq.c
@@ -0,0 +1,220 @@
+/*
+ *  linux/arch/arm/plat-aspeed/ast1070_irq.c
+ *
+ * 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/init.h>
+#include <linux/stddef.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <asm/system.h>
+#include <linux/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/irq.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <plat/regs-ast1070-intc.h>
+
+#define irq_to_c0_vic(irq_no)	(irq_no-IRQ_C0_VIC_CHAIN_START)
+
+static void ast1070_c0_mask_irq(unsigned int irq)
+{
+	u32 regVal;
+//	printk("ast_c0_mask_irq %d\n",irq);
+	irq = irq_to_c0_vic(irq);	
+//	printk("ast_c0_mask_irq cvic %d\n",irq);
+	regVal = readl(AST_INTR_DIS(0));
+	regVal |= (1 << irq);
+	writel(regVal, AST_INTR_DIS(0));
+
+}
+
+static void ast1070_c0_unmask_irq(unsigned int irq)
+{
+	u32 regVal;
+//	printk("ast_c0_unmask_irq %d\n",irq);	
+	irq = irq_to_c0_vic(irq);
+//	printk("ast_c0_unmask_irq cvic %d\n",irq);	
+	regVal = readl(AST_INTR_EN(0));
+	regVal |= (1 << irq);
+	writel(regVal, AST_INTR_EN(0));
+}
+
+static struct irq_chip ast1070_c0_irq_chip = {
+	.name	= "ast1070_c0",
+	.ack	= ast1070_c0_mask_irq,
+	.mask	= ast1070_c0_mask_irq,
+	.unmask = ast1070_c0_unmask_irq,
+}; 
+
+static void
+ast1070_c0_handle_irq(unsigned int irq, struct irq_desc *desc)
+{
+	int i,cvic_irq=0;
+    unsigned long sts = readl(AST_IRQ_STS(0));
+
+	if(irq != IRQ_C0_VIC_CHAIN)
+		BUG();
+
+	desc->chip->ack(IRQ_C0_VIC_CHAIN);	
+
+    if (sts == 0) {
+            do_bad_IRQ(irq, desc);
+            return;
+    }
+
+    do {
+			for(i=0; i<AST_CVIC_NUM; i++) {
+				if((1<<i)& readl(AST_IRQ_STS(0))) {
+					cvic_irq =i;
+					break;
+				}
+			}
+            cvic_irq += IRQ_C0_VIC_CHAIN_START;
+			//dispatch IRQ 
+//			printk("dispatch ast1070 IRQ %d\n",cvic_irq);
+            generic_handle_irq(cvic_irq);
+			
+    } while (readl(AST_IRQ_STS(0)));
+	
+	desc->chip->unmask(IRQ_C0_VIC_CHAIN);
+
+}
+
+static int __init ast1070_c0_init_irq(void)
+{
+	unsigned int i;
+//	printk("ast1070_c0_init_irq **==== Start ---------------\n");	
+	/* CVIC */
+	writel(0, AST_INTR_EN(0));
+	writel(0xFFFFFFFF, AST_INTR_DIS(0));
+
+	//AST1070 total IRQ# 25 
+	for (i = 0; i < AST_CVIC_NUM; i++) 
+	{
+		IRQ_SET_HIGH_LEVEL(0,i);
+		IRQ_SET_LEVEL_TRIGGER(0,i);
+		set_irq_chip(i + IRQ_C0_VIC_CHAIN_START, &ast1070_c0_irq_chip);
+		set_irq_handler(i + IRQ_C0_VIC_CHAIN_START, handle_level_irq);
+		set_irq_flags(i + IRQ_C0_VIC_CHAIN_START, IRQF_VALID);
+	}
+	set_irq_chained_handler(IRQ_C0_VIC_CHAIN, ast1070_c0_handle_irq);
+//	printk("ast1070_init_irq **====  END ----------\n");	
+	return 0;
+}
+
+arch_initcall(ast1070_c0_init_irq);
+
+#if (CONFIG_AST1070_NR >= 2)
+#define irq_to_c1_vic(irq_no)	(irq_no-IRQ_C1_VIC_CHAIN_START)
+
+static void ast1070_c1_mask_irq(unsigned int irq)
+{
+	u32 regVal;
+//	printk("ast_mask_irq %d\n",irq);
+	irq = irq_to_c1_vic(irq);	
+//	printk("ast_mask_irq cvic %d\n",irq);
+	regVal = readl(AST_INTR_DIS(1));
+	regVal |= (1 << irq);
+	writel(regVal, AST_INTR_DIS(1));
+
+}
+
+static void ast1070_c1_unmask_irq(unsigned int irq)
+{
+	u32 regVal;
+//	printk("ast_unmask_irq %d\n",irq);	
+	irq = irq_to_c1_vic(irq);
+//	printk("ast_unmask_irq cvic %d\n",irq);	
+	regVal = readl(AST_INTR_EN(1));
+	regVal |= (1 << irq);
+	writel(regVal, AST_INTR_EN(1));
+}
+
+static struct irq_chip ast1070_c1_irq_chip = {
+	.name	= "ast1070_c1",
+	.ack	= ast1070_c1_mask_irq,
+	.mask	= ast1070_c1_mask_irq,
+	.unmask = ast1070_c1_unmask_irq,
+}; 
+
+static void
+ast1070_c1_handle_irq(unsigned int irq, struct irq_desc *desc)
+{
+	int i,cvic_irq=0;
+    unsigned long sts = readl(AST_IRQ_STS(1));
+
+	if(irq != IRQ_C1_VIC_CHAIN)
+		BUG();
+
+	desc->chip->ack(IRQ_C1_VIC_CHAIN);	
+
+    if (sts == 0) {
+            do_bad_IRQ(irq, desc);
+            return;
+    }
+
+    do {
+			for(i=0; i<AST_CVIC_NUM; i++) {
+				if((1<<i)& readl(AST_IRQ_STS(1))) {
+					cvic_irq =i;
+					break;
+				}
+			}
+            cvic_irq += IRQ_C1_VIC_CHAIN_START;
+			//dispatch IRQ 
+//			printk("dispatch ast1070 IRQ %d\n",cvic_irq);
+            generic_handle_irq(cvic_irq);
+			
+    } while (readl(AST_IRQ_STS(1)));
+
+	desc->chip->unmask(IRQ_C1_VIC_CHAIN);
+
+}
+
+static int __init ast1070_c1_init_irq(void)
+{
+	unsigned int i;
+//	printk("ast1070_c1_init_irq **==== Start ---------------\n");	
+	/* CVIC */
+	writel(0, AST_INTR_EN(1));
+	writel(0xFFFFFFFF, AST_INTR_DIS(1));
+
+	//AST1070 total IRQ# 25 
+	for (i = 0; i < AST_CVIC_NUM; i++) 
+	{
+		IRQ_SET_HIGH_LEVEL(1,i);
+		IRQ_SET_LEVEL_TRIGGER(1,i);
+		set_irq_chip(i + IRQ_C1_VIC_CHAIN_START, &ast1070_c1_irq_chip);
+		set_irq_handler(i + IRQ_C1_VIC_CHAIN_START, handle_level_irq);
+		set_irq_flags(i + IRQ_C1_VIC_CHAIN_START, IRQF_VALID);
+	}
+	set_irq_chained_handler(IRQ_C1_VIC_CHAIN, ast1070_c1_handle_irq);
+//	printk("ast1070_init_irq **====  END ----------\n");	
+	return 0;
+}
+
+arch_initcall(ast1070_c1_init_irq);
+
+#endif
diff --git a/arch/arm/plat-aspeed/dev-adc.c b/arch/arm/plat-aspeed/dev-adc.c
new file mode 100644
index 0000000..e8d325a
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-adc.c
@@ -0,0 +1,76 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-adc.c
+* Author        : Ryan chen
+* Description   : ASPEED ADC Device
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/08/06 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#if defined(CONFIG_COLDFIRE)
+#include <asm/sizes.h>
+
+#include <asm/arch/irqs.h>
+#include <asm/arch/platform.h>
+#include <asm/arch/devs.h>
+#include <asm/arch/ast-scu.h>
+#else
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+#endif
+
+/* --------------------------------------------------------------------
+ *  ADC
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SENSORS_AST_ADC) || defined(CONFIG_SENSORS_AST_ADC_MODULE) || defined(CONFIG_SENSORS_AST1010_ADC) || defined(CONFIG_SENSORS_AST1010_ADC_MODULE)
+static struct resource ast_adc_resources[] = {
+	[0] = {
+		.start = AST_ADC_BASE,
+		.end = AST_ADC_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_ADC,
+		.end = IRQ_ADC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_adc_device = {
+	.name = "ast_adc",
+	.id = 0,
+	.resource = ast_adc_resources,
+	.num_resources = ARRAY_SIZE(ast_adc_resources),
+};
+
+void __init ast_add_device_adc(void)
+{
+	//SCU ADC CTRL Reset
+	ast_scu_init_adc();	
+
+	platform_device_register(&ast_adc_device);
+}
+#else
+void __init ast_add_device_adc(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-ci2c.c b/arch/arm/plat-aspeed/dev-ci2c.c
new file mode 100644
index 0000000..875639f
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-ci2c.c
@@ -0,0 +1,521 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-ci2c.c
+* Author        : Ryan chen
+* Description   : ASPEED I2C Device
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/07/30 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+
+#include <asm/io.h>
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/ast_i2c.h>
+
+#include <plat/devs.h>
+#include <plat/regs-iic.h>
+#include <plat/ast-scu.h>
+#include <plat/ast1070-scu.h>
+/* --------------------------------------------------------------------
+ *  CI2C
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_I2C_AST1070) || defined(CONFIG_I2C_AST1070_MODULE)
+
+static struct ast_i2c_driver_data ast_ci2c_data = {
+	.bus_clk = 100000,		//bus clock 100KHz	
+	.master_dma = DMA_MODE,
+	.slave_dma = BYTE_MODE,
+#ifdef CONFIG_AST_I2C_SLAVE_MODE	
+	.slave_xfer = i2c_slave_xfer,
+	.slave_init = i2c_slave_init,
+#endif	
+#ifdef CONFIG_AST_LPC_PLUS
+	//use lpc+ clock	
+	.get_i2c_clock = ast_get_lhclk,
+#else 
+	.get_i2c_clock = ast_get_d2_pll_clk,
+#endif
+};
+
+static u64 ast_i2c_dma_mask = 0xffffffffUL;
+static struct resource ast_ci2c_dev1_resources[] = {
+	[0] = {
+		.start = AST_C0_I2C_BASE + AST_CI2C_DEVICE1,
+		.end = AST_C0_I2C_BASE + AST_CI2C_DEVICE1 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C0_I2C,
+		.end = IRQ_C0_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_ci2c_dev1_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 0,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_ci2c_data,
+	},
+	.resource = ast_ci2c_dev1_resources,
+	.num_resources = ARRAY_SIZE(ast_ci2c_dev1_resources),
+};
+
+static struct resource ast_ci2c_dev2_resources[] = {
+	[0] = {
+		.start = AST_C0_I2C_BASE + AST_CI2C_DEVICE2,
+		.end = AST_C0_I2C_BASE + AST_CI2C_DEVICE2 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C0_I2C,
+		.end = IRQ_C0_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_ci2c_dev2_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 1,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_ci2c_data,		
+	},
+	.resource = ast_ci2c_dev2_resources,
+	.num_resources = ARRAY_SIZE(ast_ci2c_dev2_resources),
+};
+
+static struct resource ast_ci2c_dev3_resources[] = {
+	[0] = {
+		.start = AST_C0_I2C_BASE + AST_CI2C_DEVICE3,
+		.end = AST_C0_I2C_BASE + AST_CI2C_DEVICE3 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C0_I2C,
+		.end = IRQ_C0_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_ci2c_dev3_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 2,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_ci2c_data,		
+	},
+	.resource = ast_ci2c_dev3_resources,
+	.num_resources = ARRAY_SIZE(ast_ci2c_dev3_resources),
+};
+
+static struct resource ast_ci2c_dev4_resources[] = {
+	[0] = {
+		.start = AST_C0_I2C_BASE + AST_CI2C_DEVICE4,
+		.end = AST_C0_I2C_BASE + AST_CI2C_DEVICE4 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C0_I2C,
+		.end = IRQ_C0_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_ci2c_dev4_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 3,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_ci2c_data,		
+	},
+	.resource = ast_ci2c_dev4_resources,
+	.num_resources = ARRAY_SIZE(ast_ci2c_dev4_resources),
+};
+
+static struct resource ast_ci2c_dev5_resources[] = {
+	[0] = {
+		.start = AST_C0_I2C_BASE + AST_CI2C_DEVICE5,
+		.end = AST_C0_I2C_BASE + AST_CI2C_DEVICE5 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C0_I2C,
+		.end = IRQ_C0_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_ci2c_dev5_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 4,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_ci2c_data,		
+	},
+	.resource = ast_ci2c_dev5_resources,
+	.num_resources = ARRAY_SIZE(ast_ci2c_dev5_resources),
+};
+
+static struct resource ast_ci2c_dev6_resources[] = {
+	[0] = {
+		.start = AST_C0_I2C_BASE + AST_CI2C_DEVICE6,
+		.end = AST_C0_I2C_BASE + AST_CI2C_DEVICE6 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C0_I2C,
+		.end = IRQ_C0_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_ci2c_dev6_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 5,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_ci2c_data,		
+	},
+	.resource = ast_ci2c_dev6_resources,
+	.num_resources = ARRAY_SIZE(ast_ci2c_dev6_resources),
+};
+
+static struct resource ast_ci2c_dev7_resources[] = {
+	[0] = {
+		.start = AST_C0_I2C_BASE + AST_CI2C_DEVICE7,
+		.end = AST_C0_I2C_BASE + AST_CI2C_DEVICE7 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C0_I2C,
+		.end = IRQ_C0_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_ci2c_dev7_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 6,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_ci2c_data,		
+	},
+	.resource = ast_ci2c_dev7_resources,
+	.num_resources = ARRAY_SIZE(ast_ci2c_dev7_resources),
+};
+
+static struct resource ast_ci2c_dev8_resources[] = {
+	[0] = {
+		.start = AST_C0_I2C_BASE + AST_CI2C_DEVICE8,
+		.end = AST_C0_I2C_BASE + AST_CI2C_DEVICE8 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C0_I2C,
+		.end = IRQ_C0_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_ci2c_dev8_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 7,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_ci2c_data,		
+	},
+	.resource = ast_ci2c_dev8_resources,
+	.num_resources = ARRAY_SIZE(ast_ci2c_dev8_resources),
+};
+
+//
+#if (CONFIG_AST1070_NR >= 2)
+
+static struct ast_i2c_driver_data ast_c1_i2c_data = {
+	.bus_clk = 100000,		//bus clock 100KHz	
+	.master_dma = DMA_MODE,
+	.slave_dma = BYTE_MODE,
+#ifdef CONFIG_AST_I2C_SLAVE_MODE	
+	.slave_xfer = i2c_slave_xfer,
+	.slave_init = i2c_slave_init,
+#endif	
+#ifdef CONFIG_ARCH_AST2300
+		.get_i2c_clock = ast_get_d2_pll_clk,
+#else //AST2400 use lpc+ clock	
+		.get_i2c_clock = ast_get_lhclk,
+#endif
+};
+
+static struct resource ast_c1_i2c_dev1_resources[] = {
+	[0] = {
+		.start = AST_C1_I2C_BASE + AST_CI2C_DEVICE1,
+		.end = AST_C1_I2C_BASE + AST_CI2C_DEVICE1 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C1_I2C,
+		.end = IRQ_C1_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_c1_i2c_dev1_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 8 + 0,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_c1_i2c_data,
+	},
+	.resource = ast_c1_i2c_dev1_resources,
+	.num_resources = ARRAY_SIZE(ast_c1_i2c_dev1_resources),
+};
+
+static struct resource ast_c1_i2c_dev2_resources[] = {
+	[0] = {
+		.start = AST_C1_I2C_BASE + AST_CI2C_DEVICE2,
+		.end = AST_C1_I2C_BASE + AST_CI2C_DEVICE2 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C1_I2C,
+		.end = IRQ_C1_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_c1_i2c_dev2_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 8 + 1,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_c1_i2c_data,		
+	},
+	.resource = ast_c1_i2c_dev2_resources,
+	.num_resources = ARRAY_SIZE(ast_c1_i2c_dev2_resources),
+};
+
+static struct resource ast_c1_i2c_dev3_resources[] = {
+	[0] = {
+		.start = AST_C1_I2C_BASE + AST_CI2C_DEVICE3,
+		.end = AST_C1_I2C_BASE + AST_CI2C_DEVICE3 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C1_I2C,
+		.end = IRQ_C1_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_c1_i2c_dev3_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 8 + 2,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_c1_i2c_data,		
+	},
+	.resource = ast_c1_i2c_dev3_resources,
+	.num_resources = ARRAY_SIZE(ast_c1_i2c_dev3_resources),
+};
+
+static struct resource ast_c1_i2c_dev4_resources[] = {
+	[0] = {
+		.start = AST_C1_I2C_BASE + AST_CI2C_DEVICE4,
+		.end = AST_C1_I2C_BASE + AST_CI2C_DEVICE4 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C1_I2C,
+		.end = IRQ_C1_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_c1_i2c_dev4_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 8 + 3,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_c1_i2c_data,		
+	},
+	.resource = ast_c1_i2c_dev4_resources,
+	.num_resources = ARRAY_SIZE(ast_c1_i2c_dev4_resources),
+};
+
+static struct resource ast_c1_i2c_dev5_resources[] = {
+	[0] = {
+		.start = AST_C1_I2C_BASE + AST_CI2C_DEVICE5,
+		.end = AST_C1_I2C_BASE + AST_CI2C_DEVICE5 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C1_I2C,
+		.end = IRQ_C1_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_c1_i2c_dev5_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 8 + 4,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_c1_i2c_data,		
+	},
+	.resource = ast_c1_i2c_dev5_resources,
+	.num_resources = ARRAY_SIZE(ast_c1_i2c_dev5_resources),
+};
+
+static struct resource ast_c1_i2c_dev6_resources[] = {
+	[0] = {
+		.start = AST_C1_I2C_BASE + AST_CI2C_DEVICE6,
+		.end = AST_C1_I2C_BASE + AST_CI2C_DEVICE6 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C1_I2C,
+		.end = IRQ_C1_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_c1_i2c_dev6_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 8 + 5,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_c1_i2c_data,		
+	},
+	.resource = ast_c1_i2c_dev6_resources,
+	.num_resources = ARRAY_SIZE(ast_c1_i2c_dev6_resources),
+};
+
+static struct resource ast_c1_i2c_dev7_resources[] = {
+	[0] = {
+		.start = AST_C1_I2C_BASE + AST_CI2C_DEVICE7,
+		.end = AST_C1_I2C_BASE + AST_CI2C_DEVICE7 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C1_I2C,
+		.end = IRQ_C1_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_c1_i2c_dev7_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 8 + 6,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_c1_i2c_data,		
+	},
+	.resource = ast_c1_i2c_dev7_resources,
+	.num_resources = ARRAY_SIZE(ast_c1_i2c_dev7_resources),
+};
+
+static struct resource ast_c1_i2c_dev8_resources[] = {
+	[0] = {
+		.start = AST_C1_I2C_BASE + AST_CI2C_DEVICE8,
+		.end = AST_C1_I2C_BASE + AST_CI2C_DEVICE8 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_C1_I2C,
+		.end = IRQ_C1_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_c1_i2c_dev8_device = {
+	.name = "ast-i2c",
+	.id = NUM_BUS + 8 + 7,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_c1_i2c_data,		
+	},
+	.resource = ast_c1_i2c_dev8_resources,
+	.num_resources = ARRAY_SIZE(ast_c1_i2c_dev8_resources),
+};
+#endif
+//
+/*-------------------------------------*/
+void __init ast_add_device_ci2c(void)
+{
+	ast1070_scu_init_i2c(0);
+
+	ast_ci2c_data.reg_gr = IO_ADDRESS2(AST_C0_I2C_BASE);
+	if (!ast_ci2c_data.reg_gr) {
+		printk("ast_add_device_i2c ERROR \n");
+		return;
+	}
+	platform_device_register(&ast_ci2c_dev1_device);	
+	platform_device_register(&ast_ci2c_dev2_device);	
+	platform_device_register(&ast_ci2c_dev3_device);	
+	platform_device_register(&ast_ci2c_dev4_device);	
+	platform_device_register(&ast_ci2c_dev5_device); 
+	platform_device_register(&ast_ci2c_dev6_device); 
+	platform_device_register(&ast_ci2c_dev7_device); 
+	platform_device_register(&ast_ci2c_dev8_device); 
+
+
+#if (CONFIG_AST1070_NR >= 2)
+
+	ast1070_scu_init_i2c(1);
+
+	ast_c1_i2c_data.reg_gr = IO_ADDRESS2(AST_C1_I2C_BASE);
+	if (!ast_c1_i2c_data.reg_gr) {
+		printk("ast_add_device_i2c ERROR \n");
+		return;
+	}
+	platform_device_register(&ast_c1_i2c_dev1_device); 
+	platform_device_register(&ast_c1_i2c_dev2_device); 
+	platform_device_register(&ast_c1_i2c_dev3_device); 
+	platform_device_register(&ast_c1_i2c_dev4_device); 
+	platform_device_register(&ast_c1_i2c_dev5_device); 
+	platform_device_register(&ast_c1_i2c_dev6_device); 
+	platform_device_register(&ast_c1_i2c_dev7_device); 
+	platform_device_register(&ast_c1_i2c_dev8_device); 
+#endif
+
+}
+#else
+void __init ast_add_device_ci2c(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-clpc.c b/arch/arm/plat-aspeed/dev-clpc.c
new file mode 100644
index 0000000..d9fde7a
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-clpc.c
@@ -0,0 +1,240 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-clpc.c
+* Author        : Ryan chen
+* Description   : ASPEED LPC Controller
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/11/29 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+
+
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+
+
+/* --------------------------------------------------------------------
+ *  LPC
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_CLPC) || defined(CONFIG_CLPC_MODULE)
+static u64 aspeed_lpc_dma_mask = 0xffffffffUL;
+
+static struct resource aspeed_clpc0_resource[] = {
+	[0] = {
+		.start = AST_CLPC1_BASE,
+		.end = AST_CLPC1_BASE + SZ_4K,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_N1_KCS,
+		.end = IRQ_N1_KCS,
+		.flags = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start = IRQ_N1_UART,
+		.end = IRQ_N1_UART,
+		.flags = IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start = IRQ_N1_MAILBOX,
+		.end = IRQ_N1_MAILBOX,
+		.flags = IORESOURCE_IRQ,
+	},
+	[4] = {
+		.start = IRQ_N1_PORT80,
+		.end = IRQ_N1_PORT80,
+		.flags = IORESOURCE_IRQ,
+	},
+	[4] = {
+		.start = IRQ_N1_RESET,
+		.end = IRQ_N1_RESET,
+		.flags = IORESOURCE_IRQ,
+	},	
+};
+
+static struct platform_device aspeed_clpc0_device = {
+	.name	= "aspeed_lpc",
+    .id = 0,
+    .dev = {
+            .dma_mask = &aspeed_lpc_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+    },
+	.resource = aspeed_clpc0_resource,
+	.num_resources = ARRAY_SIZE(aspeed_clpc0_resource),
+};
+
+static struct resource aspeed_clpc1_resource[] = {
+	[0] = {
+		.start = AST_CLPC2_BASE,
+		.end = AST_CLPC2_BASE + SZ_4K,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_N2_KCS,
+		.end = IRQ_N2_KCS,
+		.flags = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start = IRQ_N2_UART,
+		.end = IRQ_N2_UART,
+		.flags = IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start = IRQ_N2_MAILBOX,
+		.end = IRQ_N2_MAILBOX,
+		.flags = IORESOURCE_IRQ,
+	},
+	[4] = {
+		.start = IRQ_N2_PORT80,
+		.end = IRQ_N2_PORT80,
+		.flags = IORESOURCE_IRQ,
+	},
+	[4] = {
+		.start = IRQ_N2_RESET,
+		.end = IRQ_N2_RESET,
+		.flags = IORESOURCE_IRQ,
+	},	
+};
+
+static struct platform_device aspeed_clpc1_device = {
+	.name	= "aspeed_lpc",
+    .id = 1,
+    .dev = {
+            .dma_mask = &aspeed_lpc_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+    },
+	.resource = aspeed_clpc1_resource,
+	.num_resources = ARRAY_SIZE(aspeed_clpc1_resource),
+};
+
+static struct resource aspeed_clpc2_resource[] = {
+	[0] = {
+		.start = AST_CLPC3_BASE,
+		.end = AST_CLPC3_BASE + SZ_4K,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_N3_KCS,
+		.end = IRQ_N3_KCS,
+		.flags = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start = IRQ_N3_UART,
+		.end = IRQ_N3_UART,
+		.flags = IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start = IRQ_N3_MAILBOX,
+		.end = IRQ_N3_MAILBOX,
+		.flags = IORESOURCE_IRQ,
+	},
+	[4] = {
+		.start = IRQ_N3_PORT80,
+		.end = IRQ_N3_PORT80,
+		.flags = IORESOURCE_IRQ,
+	},
+	[4] = {
+		.start = IRQ_N3_RESET,
+		.end = IRQ_N3_RESET,
+		.flags = IORESOURCE_IRQ,
+	},	
+};
+
+static struct platform_device aspeed_clpc2_device = {
+	.name	= "aspeed_lpc",
+    .id = 2,
+    .dev = {
+            .dma_mask = &aspeed_lpc_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+    },
+	.resource = aspeed_clpc2_resource,
+	.num_resources = ARRAY_SIZE(aspeed_clpc2_resource),
+};
+
+static struct resource aspeed_clpc3_resource[] = {
+	[0] = {
+		.start = AST_CLPC4_BASE,
+		.end = AST_CLPC4_BASE + SZ_4K,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_N4_KCS,
+		.end = IRQ_N4_KCS,
+		.flags = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start = IRQ_N4_UART,
+		.end = IRQ_N4_UART,
+		.flags = IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start = IRQ_N4_MAILBOX,
+		.end = IRQ_N4_MAILBOX,
+		.flags = IORESOURCE_IRQ,
+	},
+	[4] = {
+		.start = IRQ_N4_PORT80,
+		.end = IRQ_N4_PORT80,
+		.flags = IORESOURCE_IRQ,
+	},
+	[4] = {
+		.start = IRQ_N4_RESET,
+		.end = IRQ_N4_RESET,
+		.flags = IORESOURCE_IRQ,
+	},	
+};
+
+static struct platform_device aspeed_clpc3_device = {
+	.name	= "aspeed_lpc",
+    .id = 3,
+    .dev = {
+            .dma_mask = &aspeed_lpc_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+    },
+	.resource = aspeed_clpc3_resource,
+	.num_resources = ARRAY_SIZE(aspeed_clpc3_resource),
+};
+
+void __init aspeed_add_device_clpc(void)
+{
+//	it should enable at u-boot
+//	aspeed_scu_init_lpc();
+
+	platform_device_register(&aspeed_clpc0_device);
+	platform_device_register(&aspeed_clpc1_device);
+	platform_device_register(&aspeed_clpc2_device);
+	platform_device_register(&aspeed_clpc3_device);	
+}
+#else
+void __init aspeed_add_device_clpc(void) {}
+#endif
+
diff --git a/arch/arm/plat-aspeed/dev-cuart.c b/arch/arm/plat-aspeed/dev-cuart.c
new file mode 100644
index 0000000..8731f7c
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-cuart.c
@@ -0,0 +1,197 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-cuart.c
+* Author        : Ryan chen
+*
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+* History      :
+*    1. 2012/09/15 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <mach/hardware.h>
+#include <mach/ast-uart-dma.h>
+
+#include <plat/ast1070-devs.h>
+#include <plat/ast1070-scu.h>
+
+/* --------------------------------------------------------------------
+ * UART
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_ARCH_AST1070)
+static struct ast_uart_dma_data c0_uart0_dma_data = {
+	.chip_no = 0,	
+	.dma_ch = 0,
+};
+
+static struct ast_uart_dma_data c0_uart1_dma_data = {
+	.chip_no = 0,
+	.dma_ch = 1,
+};
+
+static struct ast_uart_dma_data c0_uart2_dma_data = {
+	.chip_no = 0,
+	.dma_ch = 2,
+};
+
+static struct ast_uart_dma_data c0_uart3_dma_data = {
+	.chip_no = 0,
+	.dma_ch = 3,
+};
+
+#if (CONFIG_AST1070_NR >=2)
+static struct ast_uart_dma_data c1_uart0_dma_data = {
+	.chip_no = 1,	
+	.dma_ch = 0,
+};
+
+static struct ast_uart_dma_data c1_uart1_dma_data = {
+	.chip_no = 1,
+	.dma_ch = 1,
+};
+
+static struct ast_uart_dma_data c1_uart2_dma_data = {
+	.chip_no = 1,
+	.dma_ch = 2,
+};
+
+static struct ast_uart_dma_data c1_uart3_dma_data = {
+	.chip_no = 1,
+	.dma_ch = 3,
+};
+#endif
+
+static struct plat_serial8250_port ast1070_c_uart_data[] = {
+	{
+		.mapbase	= AST_C0_UART0_BASE,
+		.membase	= (char*)(IO_ADDRESS2(AST_C0_UART0_BASE)),
+		.irq		= IRQ_C0_N1_UART,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.private_data = &c0_uart0_dma_data,
+	},
+	{
+		.mapbase	= AST_C0_UART1_BASE,
+		.membase	= (char*)(IO_ADDRESS2(AST_C0_UART1_BASE)),
+		.irq		= IRQ_C0_N2_UART,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.private_data = &c0_uart1_dma_data,
+	},	
+	{
+		.mapbase	= AST_C0_UART2_BASE,
+		.membase	= (char*)(IO_ADDRESS2(AST_C0_UART2_BASE)),
+		.irq		= IRQ_C0_N3_UART,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype 	= UPIO_MEM,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.private_data = &c0_uart2_dma_data,
+	},	
+	{
+		.mapbase	= AST_C0_UART3_BASE,
+		.membase	= (char*)(IO_ADDRESS2(AST_C0_UART3_BASE)),
+		.irq		= IRQ_C0_N4_UART,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype 	= UPIO_MEM,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.private_data = &c0_uart3_dma_data,
+	},		
+#if (CONFIG_AST1070_NR >=2)
+	{
+		.mapbase	= AST_C1_UART0_BASE,
+		.membase	= (char*)(IO_ADDRESS2(AST_C1_UART0_BASE)),
+		.irq		= IRQ_C1_N1_UART,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype 	= UPIO_MEM,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.private_data = &c1_uart0_dma_data,
+	},
+	{
+		.mapbase	= AST_C1_UART1_BASE,
+		.membase	= (char*)(IO_ADDRESS2(AST_C1_UART1_BASE)),
+		.irq		= IRQ_C1_N2_UART,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype 	= UPIO_MEM,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.private_data = &c1_uart1_dma_data,
+	},	
+	{
+		.mapbase	= AST_C1_UART2_BASE,
+		.membase	= (char*)(IO_ADDRESS2(AST_C1_UART2_BASE)),
+		.irq		= IRQ_C1_N3_UART,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype 	= UPIO_MEM,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.private_data = &c1_uart2_dma_data,
+	},	
+	{
+		.mapbase	= AST_C1_UART3_BASE,
+		.membase	= (char*)(IO_ADDRESS2(AST_C1_UART3_BASE)),
+		.irq		= IRQ_C1_N4_UART,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype 	= UPIO_MEM,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.private_data = &c1_uart3_dma_data,
+	},		
+#endif
+	{ },
+};
+
+struct platform_device ast1070_c_uart_device = {
+#ifdef CONFIG_SERIAL_AST_DMA_UART	
+	.name	= "ast-uart-dma",
+#else
+	.name	= "serial8250",
+#endif	
+	.id		= PLAT8250_DEV_PLATFORM1,
+	.dev			= {
+		.platform_data	= ast1070_c_uart_data,
+	},	
+};
+
+void __init ast_add_device_cuart(void)
+{
+	int i;//j;
+	for(i=0;i<CONFIG_AST1070_NR;i++) {
+		//reset 4 UART 
+		ast1070_scu_init_uart(i);
+		//Please don't enable : Feature remove
+//		for(j=0;j<4;j++) 
+//			ast1070_multi_func_uart(i, j);
+	}
+	
+	platform_device_register(&ast1070_c_uart_device);	
+}
+#else
+void __init ast_add_device_cuart(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-ehci.c b/arch/arm/plat-aspeed/dev-ehci.c
new file mode 100644
index 0000000..8c34a63
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-ehci.c
@@ -0,0 +1,73 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-ehci.c
+* Author        : Ryan chen
+* Description   : ASPEED EHCI Device
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/07/30 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+
+
+/* --------------------------------------------------------------------
+ *  EHCI
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_USB_EHCI_AST) || defined(CONFIG_USB_EHCI_AST_MODULE)
+static struct resource ast_echi_resource[] = {
+	[0] = {
+		.start = AST_EHCI_BASE,
+		.end = AST_EHCI_BASE + SZ_256,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_EHCI,
+		.end = IRQ_EHCI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ast_ehci_dma_mask = 0xffffffffUL;
+
+static struct platform_device ast_ehci_device = {
+	.name	= "ehci-ast",
+    .id = 0,
+    .dev = {
+            .dma_mask = &ast_ehci_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+    },
+	.resource = ast_echi_resource,
+	.num_resources = ARRAY_SIZE(ast_echi_resource),
+};
+
+void __init ast_add_device_ehci(void)
+{
+	ast_scu_multi_func_usb20_host_hub(1);
+	ast_scu_init_usb20();
+
+	platform_device_register(&ast_ehci_device);
+}
+#else
+void __init ast_add_device_ehci(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-eth.c b/arch/arm/plat-aspeed/dev-eth.c
new file mode 100644
index 0000000..5d33e33
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-eth.c
@@ -0,0 +1,201 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-eth.c
+* Author        : Ryan Chen
+* Description   : Aspeed Ethernet Device
+*
+* Copyright (C) ASPEED Technology 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
+
+*   History      :
+*    1. 2012/08/24 Ryan Chen initial
+*
+********************************************************************************/
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <mach/ftgmac100_drv.h>
+
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+
+/* --------------------------------------------------------------------
+ *  Ethernet
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_ASPEEDMAC) || defined(CONFIG_ASPEEDMAC_MODULE)
+#ifdef AST_MAC0_BASE
+static struct ftgmac100_eth_data ast_eth0_data = {
+	.dev_addr = { 0x00, 0x84, 0x14, 0xA0, 0xB0, 0x22},		
+	.phy_id = 1,
+};
+
+static u64 ast_eth_dmamask = 0xffffffffUL;
+static struct resource ast_mac0_resources[] = {
+	[0] = {
+		.start = AST_MAC0_BASE,
+		.end = AST_MAC0_BASE + SZ_128K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_MAC0,
+		.end = IRQ_MAC0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ast_eth0_device = {
+	.name		= "ast_gmac",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &ast_eth_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+				.platform_data = &ast_eth0_data,
+	},
+	.resource	= ast_mac0_resources,
+	.num_resources = ARRAY_SIZE(ast_mac0_resources),
+};
+#endif
+#ifdef AST_MAC1_BASE
+static struct ftgmac100_eth_data ast_eth1_data = {
+	.dev_addr = { 0x00, 0x84, 0x14, 0xA0, 0xB0, 0x23},		
+	.phy_id = 1,
+};
+
+static struct resource ast_mac1_resources[] = {
+	[0] = {
+		.start = AST_MAC1_BASE,
+		.end = AST_MAC1_BASE + SZ_128K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_MAC1,
+		.end = IRQ_MAC1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ast_eth1_device = {
+	.name		= "ast_gmac",
+	.id		= 1,
+	.dev		= {
+				.dma_mask		= &ast_eth_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+				.platform_data = &ast_eth1_data,
+	},
+	.resource	= ast_mac1_resources,
+	.num_resources = ARRAY_SIZE(ast_mac1_resources),
+};
+#endif
+
+/*
+ * MAC1 always has MII MDC+MDIO pins to access PHY registers.  We assume MAC1
+ * always has a PHY chip, if MAC1 is enabled.
+ * U-Boot can enable MAC2 MDC+MDIO pins for a 2nd PHY, or MAC2 might be
+ * disabled (only one port), or it's sideband-RMII which has no PHY chip.
+ *
+ * Return miiPhyId==0 if the MAC cannot be accessed.
+ * Return miiPhyId==1 if the MAC registers are OK but it cannot carry traffic.
+ * Return miiPhyId==2 if the MAC can send/receive but it has no PHY chip.
+ * Else return the PHY 22-bit vendor ID, 6-bit model and 4-bit revision.
+ */
+
+void __init ast_add_device_gmac(void)
+{
+
+	u8 phy_mode,phy_inter;
+	u32 isRevA0;
+	u32 rev_id;
+
+	rev_id = ast_scu_revision_id() & 0xff;
+
+
+	if (rev_id >= 0x08 && rev_id <= 0x0f) {
+		// AST2100 FPGA board: up to 10 means rev.A0, 11 means rev.A1
+		isRevA0 = (rev_id < 11);
+	} else {
+		// Real silicon: rev.A0 has 0x00 in bits[7:0]. rev A2 = 0x02 in bits[7:0]
+		isRevA0 = 0; //((regVal & 0x00ff) == 0x00);
+//		out->isRevA2 = 1; //((regVal & 0x00ff) == 0x02);
+	}
+
+	ast_eth0_data.DF_support = !isRevA0;
+	
+	ast_scu_init_eth(0);
+	ast_scu_multi_func_eth(0);
+	
+	
+	/*
+	* D[15:11] in 0x1E6E2040 is NCSI scratch from U-Boot. D[15:14] = MAC1, D[13:12] = MAC2
+	* The meanings of the 2 bits are:
+	* 00(0): Dedicated PHY
+	* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
+	* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
+	* 11: Reserved
+	*/
+	
+	phy_mode = ast_scu_get_phy_config(0);
+	switch(phy_mode) {
+		case 0:
+			ast_eth0_data.INTEL_NCSI_EVA_support = 0;
+			ast_eth0_data.NCSI_support = 0;
+			break;
+		case 1:
+			ast_eth0_data.NCSI_support = 1;
+			break;
+		case 2:
+			ast_eth0_data.INTEL_NCSI_EVA_support = 1;
+			break;
+			
+	}
+
+	phy_inter = ast_scu_get_phy_interface(0);
+
+	// We assume the Clock Stop register does not disable the MAC1 or MAC2 clock
+	// unless Reset Control also holds the MAC in reset.
+
+	
+	platform_device_register(&ast_eth0_device);
+
+#ifdef AST_MAC1_BASE
+	ast_scu_init_eth(1);
+	ast_scu_multi_func_eth(1);	
+
+	ast_eth1_data.DF_support = !isRevA0;
+
+	phy_mode = ast_scu_get_phy_config(1);
+	switch(phy_mode) {
+		case 0:
+			ast_eth1_data.INTEL_NCSI_EVA_support = 0;
+			ast_eth1_data.NCSI_support = 0;
+			break;
+		case 1:
+			ast_eth1_data.NCSI_support = 1;
+			break;
+		case 2:
+			ast_eth1_data.INTEL_NCSI_EVA_support = 1;
+			break;
+			
+	}
+	phy_inter = ast_scu_get_phy_interface(1);
+
+	platform_device_register(&ast_eth1_device);
+
+#endif
+
+}
+#else
+void __init ast_add_device_gmac(void) {}
+#endif
+
diff --git a/arch/arm/plat-aspeed/dev-fb.c b/arch/arm/plat-aspeed/dev-fb.c
new file mode 100644
index 0000000..3673160
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-fb.c
@@ -0,0 +1,80 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-fb.c
+* Author        : Ryan Chen
+* Description   : ASPEED Frambuffer Driver
+*
+* Copyright (C) ASPEED Tech. 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
+
+*   History      :
+*    1. 2012/12/15 Ryan Chen initial
+*
+********************************************************************************/
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+
+#include <mach/ast_lcd.h>
+
+/* --------------------------------------------------------------------
+ *  ASPEED FB
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_FB_AST) || defined(CONFIG_FB_AST_MODULE)
+static struct ast_fb_plat_data fb_plat_data = {
+	.get_clk = ast_get_d2_pll_clk,
+};
+
+
+static struct resource ast_fb_resources[] = {
+	[0] = {
+		.start = AST_GRAPHIC_BASE,
+		.end = AST_GRAPHIC_BASE + SZ_1K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_CRT,
+		.end = IRQ_CRT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ast_device_fb_dmamask = 0xffffffffUL;
+struct platform_device ast_fb_device = {
+	.name		  = "ast-fb",
+	.id		  = 0,
+	.dev		= {
+		.dma_mask		= &ast_device_fb_dmamask,
+		.coherent_dma_mask	= 0xffffffffUL,
+		.platform_data= &fb_plat_data,
+	},
+	.resource	= ast_fb_resources,
+	.num_resources	= ARRAY_SIZE(ast_fb_resources),
+};
+
+void __init ast_add_device_fb(void)
+{
+	ast_scu_multi_func_crt();
+
+	ast_scu_init_crt();
+
+	platform_device_register(&ast_fb_device);
+}
+#else
+void __init ast_add_device_fb(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-gpio.c b/arch/arm/plat-aspeed/dev-gpio.c
new file mode 100644
index 0000000..356fd53
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-gpio.c
@@ -0,0 +1,68 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-rtc.c
+* Author        : Ryan chen
+* Description   : Socle Real Time Clock Device (RTC)
+*
+* Copyright (C) Socle Tech. Corp.
+* 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
+
+* History      :
+*    1. 2010/09/15 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/regs-gpio.h>
+
+#include <plat/devs.h>
+
+/* --------------------------------------------------------------------
+ *  ASPEED GPIO
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_GPIO_AST) || defined(CONFIG_GPIO_AST_MODULE)
+static struct resource ast_gpio_resource[] = {
+	[0] = {
+		.start = AST_GPIO_BASE,
+		.end = AST_GPIO_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_GPIO,
+		.end = IRQ_GPIO,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ast_device_gpio = {
+	.name		= "ast-gpio",
+	.id			= 0,
+	.num_resources	= ARRAY_SIZE(ast_gpio_resource),
+	.resource	= ast_gpio_resource,
+};
+
+extern void __init
+ast_add_device_gpio(void)
+{
+	platform_device_register(&ast_device_gpio);
+}
+
+#else
+extern void __init ast_add_device_gpio(void) {}
+#endif
+
diff --git a/arch/arm/plat-aspeed/dev-i2c.c b/arch/arm/plat-aspeed/dev-i2c.c
new file mode 100644
index 0000000..47cd152
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-i2c.c
@@ -0,0 +1,669 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-i2c.c
+* Author        : Ryan chen
+* Description   : ASPEED I2C Device
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/07/30 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <asm/io.h>
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/ast_i2c.h>
+#include <plat/devs.h>
+#include <plat/regs-iic.h>
+#include <plat/ast-scu.h>
+
+/* --------------------------------------------------------------------
+ *  I2C
+ * -------------------------------------------------------------------- */
+#ifdef AST_I2C_DEBUG
+#define I2CDBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
+#else
+#define I2CDBUG(fmt, args...)
+#endif
+
+#if defined(CONFIG_I2C_AST) || defined(CONFIG_I2C_AST_MODULE)
+
+#if defined (CONFIG_ARCH_AST2400)
+#define I2C_PAGE_SIZE 8
+struct buf_page page_info[I2C_PAGE_SIZE] = 
+{  
+	[0] = {
+		.flag = 0,
+		.page_no = 0,
+		.page_size = 256,
+		.page_addr_point = 0,	
+	},
+	[1] = {
+		.flag = 0,
+		.page_no = 1,			
+		.page_size = 256,
+		.page_addr_point = 0,		
+	},
+	[2] = {
+		.flag = 0,
+		.page_no = 2,			
+		.page_size = 256,
+		.page_addr_point = 0,
+	},
+	[3] = {
+		.flag = 0,
+		.page_no = 3,			
+		.page_size = 256,
+		.page_addr_point = 0,
+	},
+	[4] = {
+		.flag = 0,
+		.page_no = 4,			
+		.page_size = 256,
+		.page_addr_point = 0,
+	},
+	[5] = {
+		.flag = 0,
+		.page_no = 5,			
+		.page_size = 256,
+		.page_addr_point = 0,
+	},
+	[6] = {
+		.flag = 0,
+		.page_no = 6,			
+		.page_size = 256,
+		.page_addr_point = 0,
+	},
+	[7] = {
+		.flag = 0,
+		.page_no = 7,			
+		.page_size = 256,
+		.page_addr_point = 0,
+	},
+};
+
+static void pool_buff_page_init(u32 buf_pool_addr) 
+{
+	u32 offset;
+	int i ,j;
+
+	for(i=0;i<I2C_PAGE_SIZE;i++) {
+		offset = 0;
+		for(j=0;j<i;j++)
+			offset += page_info[i].page_size;
+		
+		page_info[i].page_addr = buf_pool_addr + offset;
+//		I2CDBUG( "page[%d],addr :%x \n", i, page_info[i].page_addr);
+	}
+
+}
+
+static u8 request_pool_buff_page(struct buf_page **req_page)
+{
+	int i;
+	//TODO
+	spinlock_t	lock;
+	spin_lock(&lock);	
+	for(i=0;i<I2C_PAGE_SIZE;i++) {
+		if(page_info[i].flag ==0) {
+			page_info[i].flag = 1;
+			*req_page = &page_info[i];
+//			I2CDBUG( "request page addr %x \n", page_info[i].page_addr);
+			break;
+		}
+	}
+	spin_unlock(&lock);	
+	return 0;
+}
+
+static void free_pool_buff_page(struct buf_page *req_page)
+{
+	req_page->flag = 0;
+//	I2CDBUG( "free page addr %x \n", req_page->page_addr);	
+	req_page = NULL;
+}
+
+#elif defined (CONFIG_ARCH_AST2300)
+#define I2C_PAGE_SIZE 5
+
+struct buf_page page_info[I2C_PAGE_SIZE] = 
+{  
+	[0] = {
+		.flag = 0,
+		.page_size = 128,
+	},
+	[1] = {
+		.flag = 0,
+		.page_size = 32,
+	},
+	[2] = {
+		.flag = 0,
+		.page_size = 32,
+	},
+	[3] = {
+		.flag = 0,
+		.page_size = 32,
+	},
+	[4] = {
+		.flag = 0,
+		.page_size = 32,
+	},
+};
+
+static void pool_buff_page_init(u32 buf_pool_addr) 
+{
+
+	u32 offset;
+	int i ,j;
+
+	for(i=0;i<I2C_PAGE_SIZE;i++) {
+		offset = 0;
+		for(j=0;j<i;j++)
+			offset += page_info[i].page_size;
+		
+		page_info[i].page_addr = buf_pool_addr + offset;
+		page_info[i].page_addr_point = page_info[i].page_addr/4;
+//		printk("page[%d],addr :%x , point : %d\n", i, page_info[i].page_addr, page_info[i].page_addr_point);
+	}
+}
+
+static u8 request_pool_buff_page(struct buf_page **req_page)
+{
+	int i;
+	//TODO
+	spinlock_t	lock;
+	spin_lock(&lock);	
+	for(i=0;i<I2C_PAGE_SIZE;i++) {
+		if(page_info[i].flag ==0) {
+			page_info[i].flag = 1;
+			*req_page = &page_info[i];
+			spin_unlock(&lock);
+			return 1;
+		}
+	}
+	spin_unlock(&lock);	
+	return 0;
+
+}
+
+//TODO check free ?
+static void free_pool_buff_page(struct buf_page *req_page)
+{
+	req_page->flag = 0;
+	req_page = NULL;
+}
+
+#else 
+//DO nothing
+static void pool_buff_page_init(void) {}
+static u8 request_pool_buff_page(struct buf_page **req_page) {return 0;}
+static void free_pool_buff_page(struct buf_page *req_page) {}
+#endif
+
+static struct ast_i2c_driver_data ast_i2c_data = {
+	.bus_clk = 100000,		//bus clock 100KHz	
+	.master_dma = BUFF_MODE,
+	.slave_dma = BYTE_MODE,
+	.request_pool_buff_page = request_pool_buff_page,
+	.free_pool_buff_page = free_pool_buff_page,
+#ifdef CONFIG_AST_I2C_SLAVE_MODE	
+	.slave_xfer = i2c_slave_xfer,
+	.slave_init = i2c_slave_init,
+#endif	
+	.get_i2c_clock = ast_get_pclk,
+};
+
+static u64 ast_i2c_dma_mask = 0xffffffffUL;
+static struct resource ast_i2c_dev1_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE1,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE1 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev1_device = {
+	.name = "ast-i2c",
+	.id = 0,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,
+	},
+	.resource = ast_i2c_dev1_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev1_resources),
+};
+
+static struct resource ast_i2c_dev2_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE2,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE2 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev2_device = {
+	.name = "ast-i2c",
+	.id = 1,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,		
+	},
+	.resource = ast_i2c_dev2_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev2_resources),
+};
+
+static struct resource ast_i2c_dev3_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE3,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE3 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev3_device = {
+	.name = "ast-i2c",
+	.id = 2,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,		
+	},
+	.resource = ast_i2c_dev3_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev3_resources),
+};
+
+static struct resource ast_i2c_dev4_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE4,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE4 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev4_device = {
+	.name = "ast-i2c",
+	.id = 3,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,		
+	},
+	.resource = ast_i2c_dev4_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev4_resources),
+};
+
+static struct resource ast_i2c_dev5_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE5,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE5 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev5_device = {
+	.name = "ast-i2c",
+	.id = 4,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,		
+	},
+	.resource = ast_i2c_dev5_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev5_resources),
+};
+
+static struct resource ast_i2c_dev6_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE6,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE6 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev6_device = {
+	.name = "ast-i2c",
+	.id = 5,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,		
+	},
+	.resource = ast_i2c_dev6_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev6_resources),
+};
+
+static struct resource ast_i2c_dev7_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE7,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE7 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev7_device = {
+	.name = "ast-i2c",
+	.id = 6,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,		
+	},
+	.resource = ast_i2c_dev7_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev7_resources),
+};
+
+static struct resource ast_i2c_dev8_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE8,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE8 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev8_device = {
+	.name = "ast-i2c",
+	.id = 7,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,		
+	},
+	.resource = ast_i2c_dev8_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev8_resources),
+};
+
+static struct resource ast_i2c_dev9_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE9,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE9 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev9_device = {
+	.name = "ast-i2c",
+	.id = 8,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,		
+	},
+	.resource = ast_i2c_dev9_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev9_resources),
+};
+
+#if defined(CONFIG_ARCH_AST2400)
+static struct resource ast_i2c_dev10_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE10,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE10 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev10_device = {
+	.name = "ast-i2c",
+	.id = 9,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,		
+	},
+	.resource = ast_i2c_dev10_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev10_resources),
+};
+
+static struct resource ast_i2c_dev11_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE11,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE11 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev11_device = {
+	.name = "ast-i2c",
+	.id = 10,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,		
+	},
+	.resource = ast_i2c_dev11_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev11_resources),
+};
+
+static struct resource ast_i2c_dev12_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE12,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE12 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev12_device = {
+	.name = "ast-i2c",
+	.id = 11,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,		
+	},
+	.resource = ast_i2c_dev12_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev12_resources),
+};
+
+static struct resource ast_i2c_dev13_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE13,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE13 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev13_device = {
+	.name = "ast-i2c",
+	.id = 12,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,		
+	},
+	.resource = ast_i2c_dev13_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev13_resources),
+};
+
+static struct resource ast_i2c_dev14_resources[] = {
+	[0] = {
+		.start = AST_I2C_BASE + AST_I2C_DEVICE14,
+		.end = AST_I2C_BASE + AST_I2C_DEVICE14 + 4*SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_I2C,
+		.end = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_i2c_dev14_device = {
+	.name = "ast-i2c",
+	.id = 13,
+	.dev = {
+		.dma_mask = &ast_i2c_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &ast_i2c_data,		
+	},
+	.resource = ast_i2c_dev14_resources,
+	.num_resources = ARRAY_SIZE(ast_i2c_dev14_resources),
+};
+#endif
+
+/*--------- I2C Board devices ------------*/
+//ASPEED AST2300 EVB I2C Device 
+#if defined(CONFIG_ARCH_AST2300) || defined(CONFIG_ARCH_AST2400)
+//Under I2C Dev 1
+static struct i2c_board_info __initdata ast_i2c_board_info_1[] = {
+	{
+		I2C_BOARD_INFO("cat9883", 0x4d),						
+	}
+};
+
+//Under I2C Dev 4
+static struct i2c_board_info __initdata ast_i2c_board_info_4[] = {
+	{
+		I2C_BOARD_INFO("24c128", 0x50),						
+
+		
+	}
+};
+//Under I2C Dev 8
+static struct i2c_board_info __initdata ast_i2c_board_info_8[] = {
+	{
+		I2C_BOARD_INFO("lm75b", 0x4a),						
+	}
+};
+
+#endif
+
+/*-------------------------------------*/
+void __init ast_add_device_i2c(void)
+{
+	//I2C Multi-Pin
+	ast_scu_multi_func_i2c();
+
+	//SCU I2C Reset 
+	ast_scu_init_i2c();
+
+	ast_i2c_data.reg_gr = ioremap(AST_I2C_BASE, 4*SZ_16);
+	if (!ast_i2c_data.reg_gr) {
+		printk("ast_add_device_i2c ERROR \n");
+		return;
+	}
+
+#if defined (CONFIG_ARCH_AST2400)
+	ast_i2c_data.buf_pool= ioremap(AST_I2C_BASE+0x800, 2048);
+	if (!ast_i2c_data.buf_pool) {
+		printk("ast_add_device_i2c ERROR \n");
+		return;
+	}
+#else
+	ast_i2c_data.buf_pool = ioremap(AST_I2C_BASE+0x200, 256);
+	if (!ast_i2c_data.buf_pool) {
+		printk("ast_add_device_i2c ERROR \n");
+		return;
+	}
+#endif
+	//TODO
+	pool_buff_page_init(ast_i2c_data.buf_pool); 
+	platform_device_register(&ast_i2c_dev1_device);
+	i2c_register_board_info(0, ast_i2c_board_info_1, ARRAY_SIZE(ast_i2c_board_info_1));
+	platform_device_register(&ast_i2c_dev2_device);
+	platform_device_register(&ast_i2c_dev3_device);
+	platform_device_register(&ast_i2c_dev4_device);
+	i2c_register_board_info(3, ast_i2c_board_info_4, ARRAY_SIZE(ast_i2c_board_info_4));
+	platform_device_register(&ast_i2c_dev5_device);
+	platform_device_register(&ast_i2c_dev6_device);
+	platform_device_register(&ast_i2c_dev7_device);
+	platform_device_register(&ast_i2c_dev8_device);
+	i2c_register_board_info(7, ast_i2c_board_info_8, ARRAY_SIZE(ast_i2c_board_info_8));
+	platform_device_register(&ast_i2c_dev9_device);	
+
+#if defined(CONFIG_ARCH_AST2400)
+	platform_device_register(&ast_i2c_dev10_device);
+#if defined(CONFIG_MMC_AST)
+	//Due to share pin with SD 
+#else
+	platform_device_register(&ast_i2c_dev11_device);
+	platform_device_register(&ast_i2c_dev12_device);
+	platform_device_register(&ast_i2c_dev13_device);
+	platform_device_register(&ast_i2c_dev14_device);
+#endif	
+#endif
+}
+#else
+void __init ast_add_device_i2c(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-kcs.c b/arch/arm/plat-aspeed/dev-kcs.c
new file mode 100644
index 0000000..726dbf7
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-kcs.c
@@ -0,0 +1,129 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-kcs.c
+* Author        : Ryan chen
+* Description   : ASPEED KCS
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/11/29 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+
+/* --------------------------------------------------------------------
+ *  KCS
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_AST_KCS) || defined(CONFIG_AST_KCS_MODULE)
+static u64 ast_kcs_dma_mask = 0xffffffffUL;
+
+static struct resource ast_kcs0_resource[] = {
+	[0] = {
+		.start = AST_LPC_BASE,
+		.end = AST_LPC_BASE + SZ_256,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_LPC,
+		.end = IRQ_LPC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ast_kcs0_device = {
+	.name	= "ast-kcs",
+    .id = 0,
+    .dev = {
+            .dma_mask = &ast_kcs_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+    },
+	.resource = ast_kcs0_resource,
+	.num_resources = ARRAY_SIZE(ast_kcs0_resource),
+};
+
+static struct resource ast_kcs1_resource[] = {
+	[0] = {
+		.start = AST_LPC_BASE,
+		.end = AST_LPC_BASE + SZ_256,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_LPC,
+		.end = IRQ_LPC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ast_kcs1_device = {
+	.name	= "ast-kcs",
+    .id = 1,
+    .dev = {
+            .dma_mask = &ast_kcs_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+    },
+	.resource = ast_kcs1_resource,
+	.num_resources = ARRAY_SIZE(ast_kcs1_resource),
+};
+
+static struct resource ast_kcs2_resource[] = {
+	[0] = {
+		.start = AST_LPC_BASE,
+		.end = AST_LPC_BASE + SZ_256,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_LPC,
+		.end = IRQ_LPC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ast_kcs2_device = {
+	.name	= "ast-kcs",
+    .id = 2,
+    .dev = {
+            .dma_mask = &ast_kcs_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+    },
+	.resource = ast_kcs2_resource,
+	.num_resources = ARRAY_SIZE(ast_kcs2_resource),
+};
+
+void __init ast_add_device_kcs(void)
+{
+//	platform_device_register(&ast_kcs0_device);
+//	platform_device_register(&ast_kcs1_device);
+	platform_device_register(&ast_kcs2_device);
+}
+#else
+void __init ast_add_device_kcs(void) {}
+#endif
+
diff --git a/arch/arm/plat-aspeed/dev-lpc.c b/arch/arm/plat-aspeed/dev-lpc.c
new file mode 100644
index 0000000..50eb4e6
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-lpc.c
@@ -0,0 +1,105 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-lpc.c
+* Author        : Ryan chen
+* Description   : ASPEED LPC Controller
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/11/29 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+
+
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+
+
+/* --------------------------------------------------------------------
+ *  LPC
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_LPC) || defined(CONFIG_LPC_MODULE)
+static struct resource ast_lpc_resource[] = {
+	[0] = {
+		.start = AST_LPC_BASE,
+		.end = AST_LPC_BASE + SZ_4K,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_LPC,
+		.end = IRQ_LPC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ast_lpc_dma_mask = 0xffffffffUL;
+
+static struct platform_device ast_lpc_device = {
+	.name	= "ast_lpc",
+    .id = 0,
+    .dev = {
+            .dma_mask = &ast_lpc_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+    },
+	.resource = ast_lpc_resource,
+	.num_resources = ARRAY_SIZE(ast_lpc_resource),
+};
+
+static struct resource ast_lpc_plus_resource[] = {
+	[0] = {
+		.start = AST_LPC_PLUS_BASE,
+		.end = AST_LPC_PLUS_BASE + SZ_4K,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ast_lpc_plus_device = {
+	.name	= "ast_lpc_plus",
+    .id = 1,
+    .dev = {
+            .dma_mask = &ast_lpc_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+    },
+	.resource = ast_lpc_plus_resource,
+	.num_resources = ARRAY_SIZE(ast_lpc_plus_resource),
+};
+
+void __init ast_add_device_lpc(void)
+{
+//	it should enable at u-boot
+//	ast_scu_init_lpc();
+
+	platform_device_register(&ast_lpc_device);
+	platform_device_register(&ast_lpc_plus_device);
+}
+#else
+void __init ast_add_device_lpc(void) {}
+#endif
+
diff --git a/arch/arm/plat-aspeed/dev-mbx.c b/arch/arm/plat-aspeed/dev-mbx.c
new file mode 100644
index 0000000..75baf87
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-mbx.c
@@ -0,0 +1,79 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-mbx.c
+* Author        : Ryan chen
+* Description   : ASPEED MailBox Controller
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/11/29 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+
+/* --------------------------------------------------------------------
+ *  MailBox
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_AST_MBX) || defined(CONFIG_AST_MBX_MODULE)
+static struct resource ast_mbx_resource[] = {
+	[0] = {
+		.start = AST_MBX_BASE,
+		.end = AST_MBX_BASE + SZ_256,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_MAILBOX,
+		.end = IRQ_MAILBOX,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ast_mbx_dma_mask = 0xffffffffUL;
+
+static struct platform_device ast_mbx_device = {
+	.name	= "ast-mailbox",
+    .id = 0,
+    .dev = {
+            .dma_mask = &ast_mbx_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+    },
+	.resource = ast_mbx_resource,
+	.num_resources = ARRAY_SIZE(ast_mbx_resource),
+};
+
+void __init ast_add_device_mailbox(void)
+{
+	platform_device_register(&ast_mbx_device);
+}
+#else
+void __init ast_add_device_mailbox(void) {}
+#endif
+
diff --git a/arch/arm/plat-aspeed/dev-nand.c b/arch/arm/plat-aspeed/dev-nand.c
new file mode 100644
index 0000000..f11ff31
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-nand.c
@@ -0,0 +1,331 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-nand.c
+* Author        : Ryan chen
+* Description   : ASPEED NAND Device
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/10/15 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <asm/mach/flash.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/regs-fmc.h>
+#include <asm/io.h>
+
+#include <linux/mtd/nand.h>
+
+#include <plat/ast-scu.h>
+#include <linux/mtd/mtd.h>
+
+
+
+/* --------------------------------------------------------------------
+ *   NAND Flash
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_AST) || defined(CONFIG_MTD_NAND_AST_MODULE)
+static void __iomem *fmc_regs;
+
+/* returns 0 if the nand is busy, returns 1 if the nand is ready */
+static int 
+ast_nand_dev_ready(struct mtd_info *mtd)
+{
+	int status;
+	status = (readl(fmc_regs + FMC_MISC_CTRL1) & READ_BUSY_PIN_STS) >> 3;
+	return status;
+}
+
+/* We use 2 256bytes as ECC's data length in sample code */
+static void 
+ast_enable_hwecc(struct mtd_info *mtd, int cmd)
+{
+	writel(NAND_ECC_DATA_BLK_256 | NAND_ECC_ENABLE , fmc_regs + FMC_NAND_ECC);
+
+	writel(NAND_ECC_RESET , fmc_regs + FMC_NAND_ECC);
+	
+	writel(NAND_ECC_DATA_BLK_256 | NAND_ECC_ENABLE , fmc_regs + FMC_NAND_ECC);
+}
+
+static int 
+ast_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+{
+	uint32_t ecc_1, ecc_2, ecc_3;
+
+	ecc_1 = readl(fmc_regs + FMC_NAND_ECC_GEN1);
+	ecc_2 = readl(fmc_regs + FMC_NAND_ECC_GEN2);	
+	ecc_3 = readl(fmc_regs + FMC_NAND_ECC_GEN3);	
+
+	ecc_code[0] = ecc_1;
+	ecc_code[1] = ecc_1 >> 8;
+	ecc_code[2] = ecc_1 >> 16;
+	ecc_code[3] = ecc_1 >> 24;
+	ecc_code[4] = ecc_2;
+	ecc_code[5] = (((ecc_2 >> 8) & 0x0F) | 0xF0);	//Becase flash's data value will be 0xff after flash is erased. The 256bytes mode will use 44bits to do ECC, the software needs to add 0xF0 for the last 4 bits.
+
+	return 0;
+}
+
+static int 
+ast_nand_correct_data(struct mtd_info *mtd, u_char *dat,
+				     u_char *read_ecc, u_char *calc_ecc)
+{
+	unsigned int dw_read_data[3], dw_calc_data[3];
+	unsigned int data1_check_status, data2_check_status;
+	unsigned int i, ecc_position, ecc_bit;
+
+	for (i = 0; i < 3; i++) {
+		dw_read_data[i] = 0;
+		dw_calc_data[i] = 0;
+	}
+	memcpy (dw_read_data, read_ecc, 6);
+	memcpy (dw_calc_data, calc_ecc, 6);
+	for (i = 0; i < 2; i++) {
+		writel(dw_read_data[i], fmc_regs + FMC_NAND_ECC_CK1 + (i*4));
+		writel(dw_calc_data[i], fmc_regs + FMC_NAND_ECC_GEN1 + (i*4));
+	}
+
+	data1_check_status = readl(fmc_regs + FMC_NAND_ECC_CK_R1) & 0xffff;
+	data2_check_status = (readl(fmc_regs + FMC_NAND_ECC_CK_R1) & 0xffff0000) >> 16;
+
+	if ((data1_check_status & 0x1000) && (data2_check_status & 0x1000)) {
+		return 0;
+	}
+
+	if ((data1_check_status & 0x8000) || (data2_check_status & 0x8000)) {
+		printk(KERN_ERR "uncorrectable error : ");
+		return -1;
+	}
+
+	if ((data1_check_status & 0x4000) || (data2_check_status & 0x4000)) {
+		printk ("error in ecc data\n");
+		return 1;	/* error in ecc data; no action needed */
+	}
+
+//Correctable
+	if (data1_check_status & 0x2000) {
+		printk ("correctable in data area 1\n");
+		ecc_position = (data1_check_status & 0xff8) >> 3;
+		ecc_bit = (data1_check_status & 0x07);
+		dat[ecc_position] ^= (1 << ecc_bit);
+	}
+	if (data2_check_status & 0x2000) {
+		printk ("correctable in data area 2\n");
+		ecc_position = (data2_check_status & 0xff8) >> 3;
+		ecc_bit = (data2_check_status & 0x07);
+		dat[128 + ecc_position] ^= (1 << ecc_bit);
+	}
+
+	return 1;
+}
+
+/*---------------------------------------------------------
+ * AST2300 1 NAND * 128MB
+ *--------------------------------------------------------*/
+
+static struct mtd_partition ast_nand_partition_info[] = {
+	[0] = {
+		.name	= "ASPEED NAND Flash 0",
+		.offset	= 0,
+		.size	= SZ_64M,
+	},
+	[1] = {
+		.name	= "ASPEED NAND Flash 1",
+		.offset	= MTDPART_OFS_APPEND,
+		.size	= MTDPART_SIZ_FULL
+	},
+};
+
+static const char *ast_nand_part_probes[] = { "cmdlinepart", NULL };
+
+struct platform_nand_data ast_nand_platdata = {
+	.chip = {
+		.nr_chips = 1,
+		.chip_offset = 0,
+		.nr_partitions = ARRAY_SIZE(ast_nand_partition_info),
+		.partitions = ast_nand_partition_info,
+		/* 50 us command delay time */
+		.chip_delay = 50,
+		.options = NAND_NO_AUTOINCR,
+		.part_probe_types = ast_nand_part_probes,
+	},
+	.ctrl = {
+		.hwcontrol = ast_enable_hwecc,
+		.dev_ready = ast_nand_dev_ready,
+		.select_chip = 0,
+		.calculate = ast_calculate_ecc,
+		.correct = ast_nand_correct_data,
+	},
+};
+
+#if defined(CONFIG_AST_CS0_NAND)
+static struct resource ast_nand_resource0[] = {
+	{
+		.start			= AST_CS0_DEF_BASE,
+		.end			= AST_CS0_DEF_BASE + 0x10000,
+		.flags			= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ast_nand_device0 = {
+        .name           = "ast-nand",
+        .id             = 0,
+        .dev            = {
+                .platform_data  = &ast_nand_platdata,
+        },
+        .num_resources  = ARRAY_SIZE(ast_nand_resource0),
+        .resource       = ast_nand_resource0,
+};
+#endif
+
+#if defined(CONFIG_AST_CS1_NAND)
+static struct resource ast_nand_resource1[] = {
+	{
+		.start			= AST_CS1_DEF_BASE,
+		.end			= AST_CS1_DEF_BASE + 0x10000,
+		.flags			= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ast_nand_device1 = {
+        .name           = "ast-nand",
+        .id             = 1,
+        .dev            = {
+                .platform_data  = &ast_nand_platdata,
+        },
+        .num_resources  = ARRAY_SIZE(ast_nand_resource1),
+        .resource       = ast_nand_resource1,
+};
+#endif
+
+#if defined(CONFIG_AST_CS2_NAND)
+static struct resource ast_nand_resource2[] = {
+	{
+		.start			= AST_CS2_DEF_BASE,
+		.end			= AST_CS2_DEF_BASE + 0x10000,
+		.flags			= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ast_nand_device2 = {
+        .name           = "ast-nand",
+        .id             = 2,
+        .dev            = {
+                .platform_data  = &ast_nand_platdata,
+        },
+        .num_resources  = ARRAY_SIZE(ast_nand_resource2),
+        .resource       = ast_nand_resource2,
+};
+#endif
+
+#if defined(CONFIG_AST_CS3_NAND)
+static struct resource ast_nand_resource3[] = {
+	{
+		.start			= AST_CS3_DEF_BASE,
+		.end			= AST_CS3_DEF_BASE + 0x10000,
+		.flags			= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ast_nand_device3 = {
+        .name           = "ast-nand",
+        .id             = 3,
+        .dev            = {
+                .platform_data  = &ast_nand_platdata,
+        },
+        .num_resources  = ARRAY_SIZE(ast_nand_resource3),
+        .resource       = ast_nand_resource3,
+};
+#endif
+
+#if defined(CONFIG_AST_CS4_NAND)
+static struct resource ast_nand_resource4[] = {
+	{
+		.start			= AST_CS4_DEF_BASE,
+		.end			= AST_CS4_DEF_BASE + 0x10000,
+		.flags			= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ast_nand_device4 = {
+        .name           = "ast-nand",
+        .id             = 4,
+        .dev            = {
+                .platform_data  = &ast_nand_platdata,
+        },
+        .num_resources  = ARRAY_SIZE(ast_nand_resource4),
+        .resource       = ast_nand_resource4,
+};
+#endif
+
+/*-------------------------------------*/
+void __init ast_add_device_nand(void)
+{
+	u32 tmp;
+	fmc_regs = ioremap(AST_FMC_BASE, 4*SZ_16);
+
+	ast_scu_multi_func_nand();
+	writel(0x31 , fmc_regs + FMC_MISC_CTRL1);
+
+#if defined(CONFIG_AST_CS0_NAND)
+	platform_device_register(&ast_nand_device0);
+	tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(0)) & FMC_MASK_TYPE_CS(0);
+	writel( tmp | FMC_SET_TYPE_NAND_CS(0), fmc_regs);
+	writel(0x9 , fmc_regs + FMC_CE0_CTRL);	
+#endif
+
+#if defined(CONFIG_AST_CS1_NAND)
+	ast_scu_multi_func_romcs(1);
+	tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(1)) & FMC_MASK_TYPE_CS(1);
+	writel( tmp | FMC_SET_TYPE_NAND_CS(1), fmc_regs);
+	writel(0x9 , fmc_regs + FMC_CE1_CTRL);	
+	platform_device_register(&ast_nand_device1);
+#endif
+#if defined(CONFIG_AST_CS2_NAND)
+	ast_scu_multi_func_romcs(2);
+	tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(2)) & FMC_MASK_TYPE_CS(2);
+	writel( tmp | FMC_SET_TYPE_NAND_CS(2), fmc_regs);
+	writel(0x9 , fmc_regs + FMC_CE2_CTRL);	
+	platform_device_register(&ast_nand_device2);
+#endif
+#if defined(CONFIG_AST_CS3_NAND)
+	ast_scu_multi_func_romcs(3);
+	tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(3)) & FMC_MASK_TYPE_CS(3);
+	writel( tmp | FMC_SET_TYPE_NAND_CS(3), fmc_regs);
+	writel(0x9 , fmc_regs + FMC_CE3_CTRL);
+	platform_device_register(&ast_nand_device3);
+#endif
+#if defined(CONFIG_AST_CS4_NAND)
+	ast_scu_multi_func_romcs(4);
+	tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(4)) & FMC_MASK_TYPE_CS(4);
+	writel( tmp | FMC_SET_TYPE_NAND_CS(4), fmc_regs);
+	writel(0x9 , fmc_regs + FMC_CE4_CTRL);	
+	platform_device_register(&ast_nand_device4);
+#endif
+	iounmap(fmc_regs);
+
+}
+#else
+void __init ast_add_device_nand(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-nor.c b/arch/arm/plat-aspeed/dev-nor.c
new file mode 100644
index 0000000..abf49c0
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-nor.c
@@ -0,0 +1,219 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-nor.c
+* Author        : Ryan chen
+* Description   : ASPEED NOR Device
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/08/01 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <asm/mach/flash.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/regs-fmc.h>
+#include <asm/io.h>
+#include <plat/ast-scu.h>
+
+
+/* --------------------------------------------------------------------
+ *   NOR Flash
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_AST) || defined(CONFIG_MTD_AST_MODULE)
+/*---------------------------------------------------------
+ * AST2300 1 NOR * 16MB
+ *--------------------------------------------------------*/
+static struct mtd_partition nor_partitions[] = {
+		/* bootloader (U-Boot, etc) in first sector */
+		{
+			  .name 			= "u-boot",
+			  .offset			= 0,
+			  .size 			= 0x80000,
+			  .mask_flags		= MTD_WRITEABLE, /* force read-only */
+		},
+		/* kernel */
+		{
+			  .name 			= "kernel",
+			  .offset			= MTDPART_OFS_APPEND,
+			  .size 			= 0x300000,
+		},
+		/* file system */
+		{
+			  .name 			= "ramdisk",
+			  .offset			= MTDPART_OFS_APPEND,
+			  .size 			= 0x500000,
+		},
+		{
+			  .name 			= "data",
+			  .offset			= MTDPART_OFS_APPEND,
+			  .size 			= MTDPART_SIZ_FULL,
+		}
+};
+
+static struct flash_platform_data ast_nor_data = {
+		.map_name		= "cfi_probe",
+		.width			= 2,
+		.parts			= nor_partitions,
+		.nr_parts		= ARRAY_SIZE(nor_partitions),
+};
+
+#if defined(CONFIG_AST_CS0_NOR)
+static struct resource ast_nor_resource0[] = {
+	{
+		.start			= AST_CS0_DEF_BASE,
+		.end			= AST_CS0_DEF_BASE + AST_NOR_SIZE- 1,
+		.flags			= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ast_nor_device0 = {
+        .name           = "ast-nor",
+        .id             = 0,
+        .dev            = {
+                .platform_data  = &ast_nor_data,
+        },
+        .num_resources  = ARRAY_SIZE(ast_nor_resource0),
+        .resource       = ast_nor_resource0,
+};
+#endif
+
+#if defined(CONFIG_AST_CS1_NOR)
+static struct resource ast_nor_resource1[] = {
+	{
+		.start			= AST_CS1_DEF_BASE,
+		.end			= AST_CS1_DEF_BASE + AST_NOR_SIZE- 1,
+		.flags			= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ast_nor_device1 = {
+        .name           = "ast-nor",
+        .id             = 1,
+        .dev            = {
+                .platform_data  = &ast_nor_data,
+        },
+        .num_resources  = ARRAY_SIZE(ast_nor_resource1),
+        .resource       = ast_nor_resource1,
+};
+#endif
+
+#if defined(CONFIG_AST_CS2_NOR)
+static struct resource ast_nor_resource2[] = {
+	{
+		.start			= AST_CS2_DEF_BASE,
+		.end			= AST_CS2_DEF_BASE + AST_NOR_SIZE- 1,
+		.flags			= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ast_nor_device2 = {
+        .name           = "ast-nor",
+        .id             = 2,
+        .dev            = {
+                .platform_data  = &ast_nor_data,
+        },
+        .num_resources  = ARRAY_SIZE(ast_nor_resource2),
+        .resource       = ast_nor_resource2,
+};
+#endif
+
+#if defined(CONFIG_AST_CS3_NOR)
+static struct resource ast_nor_resource3[] = {
+	{
+		.start			= AST_CS3_DEF_BASE,
+		.end			= AST_CS3_DEF_BASE + AST_NOR_SIZE- 1,
+		.flags			= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ast_nor_device3 = {
+        .name           = "ast-nor",
+        .id             = 3,
+        .dev            = {
+                .platform_data  = &ast_nor_data,
+        },
+        .num_resources  = ARRAY_SIZE(ast_nor_resource3),
+        .resource       = ast_nor_resource3,
+};
+#endif
+
+#if defined(CONFIG_AST_CS4_NOR)
+static struct resource ast_nor_resource4[] = {
+	{
+		.start			= AST_CS4_DEF_BASE,
+		.end			= AST_CS4_DEF_BASE + AST_NOR_SIZE- 1,
+		.flags			= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ast_nor_device4 = {
+        .name           = "ast-nor",
+        .id             = 4,
+        .dev            = {
+                .platform_data  = &ast_nor_data,
+        },
+        .num_resources  = ARRAY_SIZE(ast_nor_resource4),
+        .resource       = ast_nor_resource4,
+};
+#endif
+
+/*-------------------------------------*/
+void __init ast_add_device_flash(void)
+{
+	void __iomem *fmc_regs = ioremap(AST_FMC_BASE, 4*SZ_16);
+
+	ast_scu_multi_func_nor();
+
+#if defined(CONFIG_AST_CS0_NOR)
+	//Enable NOR ACK
+	ast_scu_multi_func_romcs(0);
+	platform_device_register(&ast_nor_device0);
+	writel((readl(fmc_regs) | FMC_SET_WRITE_CS(0)) & FMC_MASK_TYPE_CS(0), fmc_regs);
+#endif
+#if defined(CONFIG_AST_CS1_NOR)
+	ast_scu_multi_func_romcs(1);
+	writel((readl(fmc_regs) | FMC_SET_WRITE_CS(1)) & FMC_MASK_TYPE_CS(1), fmc_regs);
+	platform_device_register(&ast_nor_device1);
+#endif
+#if defined(CONFIG_AST_CS2_NOR)
+	ast_scu_multi_func_romcs(2);
+	writel((readl(fmc_regs) | FMC_SET_WRITE_CS(2)) & FMC_MASK_TYPE_CS(2), fmc_regs);
+	platform_device_register(&ast_nor_device2);
+#endif
+#if defined(CONFIG_AST_CS3_NOR)
+	ast_scu_multi_func_romcs(3);
+	writel((readl(fmc_regs) | FMC_SET_WRITE_CS(3)) & FMC_MASK_TYPE_CS(3), fmc_regs);
+	platform_device_register(&ast_nor_device3);
+#endif
+#if defined(CONFIG_AST_CS4_NOR)
+	ast_scu_multi_func_romcs(4);
+	writel((readl(fmc_regs) | FMC_SET_WRITE_CS(4)) & FMC_MASK_TYPE_CS(4), fmc_regs);
+	platform_device_register(&ast_nor_device4);
+#endif
+	iounmap(fmc_regs);
+
+}
+#else
+void __init ast_add_device_flash(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-peci.c b/arch/arm/plat-aspeed/dev-peci.c
new file mode 100644
index 0000000..28ad1a5
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-peci.c
@@ -0,0 +1,68 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-peci.c
+* Author        : Ryan chen
+* Description   : ASPEED PECI Device
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/08/06 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+
+
+/* --------------------------------------------------------------------
+ *  PECI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AST_PECI) || defined(CONFIG_AST_PECI_MODULE)
+static struct resource ast_peci_resources[] = {
+	[0] = {
+		.start = AST_PECI_BASE,
+		.end = AST_PECI_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_PECI,
+		.end = IRQ_PECI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device ast_peci_device = {
+	.name = "ast_peci",
+	.id = 0,
+	.resource = ast_peci_resources,
+	.num_resources = ARRAY_SIZE(ast_peci_resources),
+};
+
+void __init ast_add_device_peci(void)
+{
+	//SCU PECI CTRL Reset
+	ast_scu_init_peci();	
+
+	platform_device_register(&ast_peci_device);
+}
+#else
+void __init ast_add_device_peci(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-pwm-fan.c b/arch/arm/plat-aspeed/dev-pwm-fan.c
new file mode 100644
index 0000000..85570bb
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-pwm-fan.c
@@ -0,0 +1,80 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-pwm-fan.c
+* Author        : Ryan chen
+* Description   : ASPEED PWM-FAN Device
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/08/06 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+#include <mach/ast_pwm_techo.h>
+
+/* --------------------------------------------------------------------
+ *  PWM-FAN
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SENSORS_AST_PWM_FAN) || defined(CONFIG_SENSORS_AST_PWM_FAN_MODULE)
+static struct resource ast_pwm_fan_resources[] = {
+	[0] = {
+		.start = AST_PWM_BASE,
+		.end = AST_PWM_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_TACHO,
+		.end = IRQ_TACHO,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct ast_pwm_driver_data ast_pwm_data = {
+	.get_pwm_clock = ast_get_h_pll_clk,
+};
+
+struct platform_device ast_pwm_fan_device = {
+	.name = "ast_pwm_tacho",
+	.id = 0,
+	.dev = {
+		.platform_data = &ast_pwm_data,
+	},	
+	.resource = ast_pwm_fan_resources,
+	.num_resources = ARRAY_SIZE(ast_pwm_fan_resources),
+};
+
+void __init ast_add_device_pwm_fan(void)
+{
+	//SCU Initial 
+
+	//SCU Pin-MUX 	//PWM & TACHO 
+	ast_scu_multi_func_pwm_tacho();
+
+	//SCU PWM CTRL Reset
+	ast_scu_init_pwm_tacho();	
+
+	platform_device_register(&ast_pwm_fan_device);
+}
+#else
+void __init ast_add_device_pwm_fan(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-rtc.c b/arch/arm/plat-aspeed/dev-rtc.c
new file mode 100644
index 0000000..214aa68
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-rtc.c
@@ -0,0 +1,65 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-wdt.c
+* Author        : Ryan Chen
+* Description   : AST WDT Device
+*
+* Copyright (C)  ASPEED Technology 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
+
+*   History      :
+*    1. 2012/09/15 Ryan Chen initial
+*
+********************************************************************************/
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+
+#include <plat/devs.h>
+
+
+/* --------------------------------------------------------------------
+ *  Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_RTC_DRV_AST) || defined(CONFIG_RTC_DRV_AST_MODULE)
+
+static struct resource ast_rtc_resource[] = {
+	[0] = {
+		.start	= AST_RTC_BASE,
+		.end	= AST_RTC_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+			.start = IRQ_RTC,
+			.end = IRQ_RTC,
+			.flags = IORESOURCE_IRQ,
+	},
+	
+};
+
+static struct platform_device ast_device_rtc = {
+	.name		= "ast_rtc",
+	.id		= -1,
+	.resource       = ast_rtc_resource,
+	.num_resources  = ARRAY_SIZE(ast_rtc_resource),
+};
+
+void __init ast_add_device_rtc(void)
+{
+	platform_device_register(&ast_device_rtc);
+}
+#else
+void __init ast_add_device_rtc(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-sdhci.c b/arch/arm/plat-aspeed/dev-sdhci.c
new file mode 100644
index 0000000..bcc8cce
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-sdhci.c
@@ -0,0 +1,110 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-sdhc.c
+* Author        : Ryan chen
+* Description   : ASPEED SDHC Device
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/07/30 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast_sdhci.h>
+#include <plat/ast-scu.h>
+
+
+/* --------------------------------------------------------------------
+ *  SDHC
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_MMC_AST) || defined(CONFIG_MMC_AST_MODULE)
+static struct ast_sdhc_platform_data ast_sdhc_info = {
+        .sd_clock_src_get = ast_get_sd_clock_src,
+};
+
+static struct resource ast_sdhci0_resource[] = {
+	[0] = {
+		.start = AST_SDHC_BASE + 0x100,
+		.end = AST_SDHC_BASE + 0x100 + 0xFF,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_SDHC,
+		.end = IRQ_SDHC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource ast_sdhci1_resource[] = {
+	[0] = {
+		.start = AST_SDHC_BASE + 0x200,
+		.end = AST_SDHC_BASE + 0x200 + 0xFF,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_SDHC,
+		.end = IRQ_SDHC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ast_sdhc_dma_mask = 0xffffffffUL;
+
+static struct platform_device ast_sdhci_device0 = {
+	.name	= "ast_sdhci",
+    .id = 0,
+    .dev = {
+            .dma_mask = &ast_sdhc_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+            .platform_data = &ast_sdhc_info,
+    },
+	.resource = ast_sdhci0_resource,
+	.num_resources = ARRAY_SIZE(ast_sdhci0_resource),
+};
+
+static struct platform_device ast_sdhci_device1 = {
+	.name	= "ast_sdhci",
+    .id = 1,
+    .dev = {
+            .dma_mask = &ast_sdhc_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+            .platform_data = &ast_sdhc_info,
+    },
+	.resource = ast_sdhci1_resource,
+	.num_resources = ARRAY_SIZE(ast_sdhci1_resource),
+};
+
+void __init ast_add_device_sdhci(void)
+{
+	ast_scu_init_sdhci();
+	//multipin. Remind: AST2300FPGA only supports one port at a time
+	
+	ast_scu_multi_func_sdhc_slot1(1);
+
+	platform_device_register(&ast_sdhci_device0);
+
+	ast_scu_multi_func_sdhc_slot2(1);
+
+	platform_device_register(&ast_sdhci_device1);
+}
+#else
+void __init ast_add_device_sdhci(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-sgpio.c b/arch/arm/plat-aspeed/dev-sgpio.c
new file mode 100644
index 0000000..c6ca2c4
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-sgpio.c
@@ -0,0 +1,68 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-rtc.c
+* Author        : Ryan chen
+* Description   : Socle Real Time Clock Device (RTC)
+*
+* Copyright (C) Socle Tech. Corp.
+* 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
+
+* History      :
+*    1. 2010/09/15 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+//#include <plat/regs-sgpio.h>
+
+#include <plat/devs.h>
+
+/* --------------------------------------------------------------------
+ *  ASPEED SGPIO
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SGPIO_AST) || defined(CONFIG_SGPIO_AST_MODULE)
+static struct resource ast_sgpio_resource[] = {
+	[0] = {
+		.start = AST_SGPIO_BASE,
+		.end = AST_SGPIO_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_SGPIO,
+		.end = IRQ_SGPIO,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ast_device_sgpio = {
+	.name		= "ast-sgpio",
+	.id			= 0,
+	.num_resources	= ARRAY_SIZE(ast_sgpio_resource),
+	.resource	= ast_sgpio_resource,
+};
+
+extern void __init
+ast_add_device_sgpio(void)
+{
+	platform_device_register(&ast_device_sgpio);
+}
+
+#else
+extern void __init ast_add_device_sgpio(void) {}
+#endif
+
diff --git a/arch/arm/plat-aspeed/dev-snoop.c b/arch/arm/plat-aspeed/dev-snoop.c
new file mode 100644
index 0000000..9e286bc
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-snoop.c
@@ -0,0 +1,94 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-snoop.c
+* Author        : Ryan chen
+* Description   : ASPEED SNOOP Device
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/11/29 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-snoop.h>
+
+/* --------------------------------------------------------------------
+ *  AST SNOOP -- DMA or 80Port SNOOP 
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_SNOOP_AST) || defined(CONFIG_SNOOP_AST_MODULE)
+static u64 ast_snoop_dma_mask = 0xffffffffUL;
+	
+static struct ast_snoop_channel snoop_ch0 = {
+	.snoop_ch = 0,
+	.snoop_port = 0x80,	
+};
+
+static struct ast_snoop_channel snoop_ch1 = {
+	.snoop_ch = 1,
+	.snoop_port = 0x81,	
+};
+
+static struct ast_snoop snoop = {
+	.snoop_ch0 = &snoop_ch0,
+	.snoop_ch1 = &snoop_ch1,
+};
+
+static struct platform_device ast_snoop_device = {
+	.name	= "ast_snoop",
+    .id = 0,
+    .dev = {
+        .dma_mask = &ast_snoop_dma_mask,
+        .coherent_dma_mask = 0xffffffff,
+        .platform_data = &snoop,
+    },
+};
+
+struct ast_snoop_dma_channel snoop_dma_ch0 = {
+	.snoop_ch = 0,
+	.snoop_port = 0x3f8,	
+	.snoop_mask = 7,		
+};
+
+static struct platform_device ast_snoop_dma_device = {
+	.name	= "ast_snoop_dma",
+    .id = 0,
+    .dev = {
+        .dma_mask = &ast_snoop_dma_mask,
+        .coherent_dma_mask = 0xffffffff,
+        .platform_data = &snoop_dma_ch0,
+    },
+};
+
+void __init ast_add_device_snoop(void)
+{
+	platform_device_register(&ast_snoop_device);
+	platform_device_register(&ast_snoop_dma_device);	
+}
+#else
+void __init ast_add_device_snoop(void) {}
+#endif
+
diff --git a/arch/arm/plat-aspeed/dev-spi.c b/arch/arm/plat-aspeed/dev-spi.c
new file mode 100644
index 0000000..7ddd2e4
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-spi.c
@@ -0,0 +1,448 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-spi.c
+* Author        : Ryan chen
+* Description   : ASPEED SPI device
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/08/01 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/flash.h>
+
+#include <linux/spi/spi.h>
+
+
+#include <asm/io.h>
+#if defined(CONFIG_COLDFIRE)
+#include <asm/sizes.h>
+#include <asm/arch/ast_spi.h>
+#include <asm/arch/ast-scu.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/platform.h>
+#include <asm/arch/devs.h>
+#else
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/regs-fmc.h>
+#include <plat/ast-scu.h>
+#include <mach/ast_spi.h>
+#endif
+
+/* --------------------------------------------------------------------
+ *   SPI Ctrl, (AST SPI + FMC SPI)
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_SPI_FMC) || defined(CONFIG_SPI_FMC_MODULE) || defined(CONFIG_SPI_AST) || defined(CONFIG_SPI_AST_MODULE)
+static u32 ast_spi_calculate_divisor(u32 max_speed_hz)
+{
+	// [0] ->15 : HCLK , HCLK/16
+	u8 SPI_DIV[16] = {16, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 0};
+	u32 i, hclk, spi_cdvr=0;
+
+	hclk = ast_get_h_pll_clk();
+	for(i=1;i<17;i++) {
+		if(max_speed_hz >= (hclk/i)) {
+			spi_cdvr = SPI_DIV[i-1];
+			break;
+		}
+	}
+		
+//	printk("hclk is %d, divisor is %d, target :%d , cal speed %d\n", hclk, spi_cdvr, spi->max_speed_hz, hclk/i);
+	return spi_cdvr;
+}
+#endif
+
+#if defined(CONFIG_SPI_FMC) || defined(CONFIG_SPI_FMC_MODULE)
+static struct ast_spi_driver_data fmc_spi_data = {
+	.get_div = ast_spi_calculate_divisor,
+	.num_chipselect = 1,
+};
+
+#if defined(CONFIG_AST_CS0_SPI)
+static struct resource ast_fmc_spi_resource0[] = {
+	{
+		.start			= AST_FMC_BASE + 0x10,
+		.end			= AST_FMC_BASE + 0x10 + SZ_16,
+		.flags			= IORESOURCE_MEM,
+	},
+	{
+		.start			= AST_CS0_DEF_BASE,
+		.end			= AST_CS0_DEF_BASE + SZ_16,
+		.flags			= IORESOURCE_IO,
+	},	
+};
+static struct platform_device ast_fmc_spi_device0 = {
+        .name           = "fmc-spi",
+        .id             = 0,
+		.dev = {
+			.platform_data = &fmc_spi_data,
+		},
+        .num_resources  = ARRAY_SIZE(ast_fmc_spi_resource0),
+        .resource       = ast_fmc_spi_resource0,        
+};
+#endif
+
+#if defined(CONFIG_AST_CS1_SPI)
+static struct resource ast_fmc_spi_resource1[] = {
+	{
+		.start			= AST_FMC_BASE + 0x14,
+		.end			= AST_FMC_BASE + 0x14 + SZ_16,
+		.flags			= IORESOURCE_MEM,
+	},
+	{
+		.start			= AST_CS1_DEF_BASE,
+		.end			= AST_CS1_DEF_BASE + SZ_16,
+		.flags			= IORESOURCE_IO,
+	},	
+};
+static struct platform_device ast_fmc_spi_device1 = {
+        .name           = "fmc-spi",
+        .id             = 1,
+		.dev = {
+			.platform_data = &fmc_spi_data,
+		},
+        .num_resources  = ARRAY_SIZE(ast_fmc_spi_resource1),
+        .resource       = ast_fmc_spi_resource1,  		
+};
+#endif
+
+#if defined(CONFIG_AST_CS2_SPI)
+static struct resource ast_fmc_spi_resource2[] = {
+	{
+		.start			= AST_FMC_BASE + 0x18,
+		.end			= AST_FMC_BASE + 0x18 + SZ_16,
+		.flags			= IORESOURCE_MEM,
+	},
+	{
+		.start			= AST_CS2_DEF_BASE,
+		.end			= AST_CS2_DEF_BASE + SZ_16,
+		.flags			= IORESOURCE_IO,
+	},	
+};
+
+static struct platform_device ast_fmc_spi_device2 = {
+        .name           = "fmc-spi",
+        .id             = 2,
+		.dev = {
+			.platform_data = &fmc_spi_data,
+		},
+        .num_resources  = ARRAY_SIZE(ast_fmc_spi_resource2),
+        .resource       = ast_fmc_spi_resource2,  		
+};
+#endif
+
+#if defined(CONFIG_AST_CS3_SPI)
+static struct resource ast_fmc_spi_resource3[] = {
+	{
+		.start			= AST_FMC_BASE + 0x1c,
+		.end			= AST_FMC_BASE + 0x1c + SZ_16,
+		.flags			= IORESOURCE_MEM,
+	},
+	{
+		.start			= AST_CS3_DEF_BASE,
+		.end			= AST_CS3_DEF_BASE + SZ_16,
+		.flags			= IORESOURCE_IO,
+	},	
+};
+
+static struct platform_device ast_fmc_spi_device3 = {
+        .name           = "fmc-spi",
+        .id             = 3,
+		.dev = {
+			.platform_data = &fmc_spi_data,
+		},
+        .num_resources  = ARRAY_SIZE(ast_fmc_spi_resource3),
+        .resource       = ast_fmc_spi_resource3,  			
+};
+#endif
+
+#if defined(CONFIG_AST_CS4_SPI)
+static struct resource ast_fmc_spi_resource4[] = {
+	{
+		.start			= AST_FMC_BASE + 0x20,
+		.end			= AST_FMC_BASE + 0x20 + SZ_16,
+		.flags			= IORESOURCE_MEM,
+	},
+	{
+		.start			= AST_CS4_DEF_BASE,
+		.end			= AST_CS4_DEF_BASE + SZ_16,
+		.flags			= IORESOURCE_IO,
+	},	
+};
+
+static struct platform_device ast_fmc_spi_device4 = {
+        .name           = "fmc-spi",
+        .id             = 4,
+		.dev = {
+			.platform_data = &fmc_spi_data,
+		},
+        .num_resources  = ARRAY_SIZE(ast_fmc_spi_resource4),
+        .resource       = ast_fmc_spi_resource4,  			
+};
+#endif
+
+#endif	//CONFIG_SPI_FMC
+
+#if defined(CONFIG_SPI_AST) || defined(CONFIG_SPI_AST_MODULE)
+static struct ast_spi_driver_data ast_spi0_data = {
+	.get_div = ast_spi_calculate_divisor,
+	.num_chipselect = 1,
+};
+
+static struct resource ast_spi_resource0[] = {
+	{
+		.start			= AST_SPI0_BASE,
+		.end			= AST_SPI0_BASE + SZ_16,
+		.flags			= IORESOURCE_MEM,
+	},
+	{
+		.start			= AST_SPI0_MEM + 0x04,
+		.end			= AST_SPI0_MEM + SZ_16,
+		.flags			= IORESOURCE_IO,
+	},	
+};
+
+static struct platform_device ast_spi_device0 = {
+        .name           = "ast-spi",
+#if defined(CONFIG_ARCH_AST1010)		
+		.id 			= 0,
+#else
+		.id             = 5,
+#endif
+		.dev = {
+			.platform_data = &ast_spi0_data,
+		},
+        .num_resources  = ARRAY_SIZE(ast_spi_resource0),
+        .resource       = ast_spi_resource0,  			
+};
+
+#if defined(AST_SPI1_BASE)
+static struct ast_spi_driver_data ast_spi1_data = {
+	.get_div = ast_spi_calculate_divisor,
+	.num_chipselect = 1,
+};
+
+static struct resource aspeed_spi1_resource[] = {
+	{
+		.start			= AST_SPI1_BASE,
+		.end			= AST_SPI1_BASE + SZ_16,
+		.flags			= IORESOURCE_MEM,
+	},
+	{
+		.start			= AST_SPI1_MEM,
+		.end			= AST_SPI1_MEM + SZ_16,
+		.flags			= IORESOURCE_IO,
+	},	
+};
+
+static struct platform_device aspeed_spi_device1 = {
+        .name           = "ast-spi",
+        .id             = 1,
+		.dev = {
+			.platform_data = &ast_spi1_data,
+		},
+        .num_resources  = ARRAY_SIZE(aspeed_spi1_resource),
+        .resource       = aspeed_spi1_resource,  			
+};
+
+#endif
+
+#endif	//CONFIG_SPI_AST
+
+#if defined(CONFIG_ARCH_AST1010)
+static struct mtd_partition ast_spi_flash_partitions[] = {
+	{
+		.name	= "uboot",
+		.offset = 0,
+		.size	= 0x00030000,
+		.mask_flags = MTD_WRITEABLE,				
+	},
+	{
+		.name	= "uboot-env",
+		.offset = MTDPART_OFS_APPEND,
+		.size	= 0x00010000,
+//		.mask_flags = MTD_WRITEABLE,
+	},
+	{
+		.name   = "uCLinux",
+		.offset = MTDPART_OFS_APPEND,
+		.size   = 0x003c0000,
+//		.mask_flags = MTD_CAP_NORFLASH,
+	},
+	{
+		.name	= "data",
+		.offset = MTDPART_OFS_APPEND,
+		.size	= MTDPART_SIZ_FULL,
+//		.mask_flags = MTD_CAP_NORFLASH,
+	}
+};
+#else
+static struct mtd_partition ast_spi_flash_partitions[] = {
+		{
+			.name	= "u-boot",
+			.offset = 0,
+			.size	= 0x80000,
+			.mask_flags	= MTD_WRITEABLE,
+		}, {
+            .name   = "kernel",
+			.offset = 0x80000,
+            .size   = 0x200000,     
+        }, {
+            .name   = "rootfs",
+			.offset = 0x300000,
+            .size   = 0x4F0000,
+		}, {
+			.name	= "env",
+			.offset = 0x7f0000,
+			.size	= 0x10000,            
+		}, {
+			.name	= "data0",
+			.offset = MTDPART_OFS_APPEND,
+			.size	= MTDPART_SIZ_FULL,
+        },
+};
+#endif
+
+static struct flash_platform_data ast_spi_flash_data = {
+#if defined(CONFIG_ARCH_AST2400)
+		.type 		  = "mx25l25635e",	//AST2400 A1
+#elif defined(CONFIG_ARCH_AST1010)
+        .type         = "mx25l6405d",
+#else		
+		.type 		  = "mx25l12805d",	//old AST2300 
+#endif		
+        .nr_parts       = ARRAY_SIZE(ast_spi_flash_partitions),
+        .parts          = ast_spi_flash_partitions,
+};
+
+static struct spi_board_info ast_spi_devices[] = {
+    {
+        .modalias    = "m25p80",
+		.platform_data  = &ast_spi_flash_data,
+        .chip_select    = 0, //.chip_select This tells your device driver which chipselect to use.
+        .max_speed_hz    = 50 * 1000 * 1000, 
+        .bus_num    = 0, //  This chooses if SPI0 or SPI1 of the SoC is used.
+     	.mode = SPI_MODE_0,
+    }, 
+    {
+        .modalias    = "spidev",
+        .chip_select    = 0,
+        .max_speed_hz    = 30 * 1000 * 1000,
+        .bus_num    = 1,
+		.mode = SPI_MODE_0,
+    },
+};
+
+#if defined(AST_SPI1_BASE)
+static struct mtd_partition ast_spi_flash1_partitions[] = {
+		{
+			.name	= "bios",
+			.offset = 0,
+			.size	= MTDPART_SIZ_FULL,
+        }
+};
+
+static struct flash_platform_data ast_spi_flash1_data = {
+        .type           = "mx25l6405d",
+//        .type           = "w25q64",		
+        .nr_parts       = ARRAY_SIZE(ast_spi_flash1_partitions),
+        .parts          = ast_spi_flash1_partitions,
+};
+
+
+static struct spi_board_info ast_spi1_devices[] = {
+    {
+        .modalias    = "m25p80",
+		.platform_data  = &ast_spi_flash1_data,
+        .chip_select    = 0, //.chip_select This tells your device driver which chipselect to use.
+        .max_speed_hz    = 100 * 1000 * 1000, 
+        .bus_num    = 1, //  This chooses if SPI0 or SPI1 of the SoC is used.
+     	.mode = SPI_MODE_0,
+    }, 
+};
+#endif
+
+#if defined(CONFIG_SPI_FMC) || defined(CONFIG_SPI_FMC_MODULE) || defined(CONFIG_SPI_AST) || defined(CONFIG_SPI_AST_MODULE)
+
+/*-------------------------------------*/
+void __init ast_add_device_spi(void)
+{
+#if defined(CONFIG_SPI_FMC) || defined(CONFIG_SPI_FMC_MODULE)
+	void __iomem *fmc_regs = ioremap(AST_FMC_BASE, 4*SZ_16);
+	u32 tmp = 0;
+
+#if defined(CONFIG_AST_CS0_SPI)
+	platform_device_register(&ast_fmc_spi_device0);
+	tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(0)) & FMC_MASK_TYPE_CS(0);
+	writel( tmp | FMC_SET_TYPE_SPI_CS(0), fmc_regs);
+#endif
+
+#if defined(CONFIG_AST_CS1_SPI)
+	ast_scu_multi_func_romcs(1);
+	tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(1)) & FMC_MASK_TYPE_CS(1);
+	writel( tmp | FMC_SET_TYPE_SPI_CS(1), fmc_regs);
+	platform_device_register(&ast_fmc_spi_device1);
+#endif
+
+#if defined(CONFIG_AST_CS2_SPI)
+	ast_scu_multi_func_romcs(2);
+	tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(2)) & FMC_MASK_TYPE_CS(2);
+	writel( tmp | FMC_SET_TYPE_SPI_CS(2), fmc_regs);
+	platform_device_register(&ast_fmc_spi_device2);
+#endif
+#if defined(CONFIG_AST_CS3_SPI)
+	ast_scu_multi_func_romcs(3);
+	tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(3)) & FMC_MASK_TYPE_CS(3);
+	writel( tmp | FMC_SET_TYPE_SPI_CS(3), fmc_regs);
+	platform_device_register(&ast_fmc_spi_device3);
+#endif
+#if defined(CONFIG_AST_CS4_SPI)
+	ast_scu_multi_func_romcs(4);
+	tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(4)) & FMC_MASK_TYPE_CS(4);
+	writel( tmp | FMC_SET_TYPE_SPI_CS(4), fmc_regs);
+	platform_device_register(&ast_fmc_spi_device4);
+#endif
+
+	iounmap(fmc_regs);
+
+#endif
+
+#if defined(CONFIG_SPI_AST) || defined(CONFIG_SPI_AST_MODULE)
+	//pin switch by trap[13:12]
+	platform_device_register(&ast_spi_device0);
+#endif
+
+	spi_register_board_info(ast_spi_devices, ARRAY_SIZE(ast_spi_devices));
+
+#if defined(AST_SPI1_BASE)
+	//AST1010 SCU CONFIG TODO .......
+	writel(readl(AST_SCU_BASE + 0x70) | 0x10,AST_SCU_BASE + 0x70);
+	platform_device_register(&aspeed_spi_device1);
+	spi_register_board_info(ast_spi1_devices, ARRAY_SIZE(ast_spi1_devices));
+#endif	
+
+}
+#else
+void __init ast_add_device_spi(void) {}
+#endif
+
+
diff --git a/arch/arm/plat-aspeed/dev-uart.c b/arch/arm/plat-aspeed/dev-uart.c
new file mode 100644
index 0000000..592ef4f
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-uart.c
@@ -0,0 +1,144 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-uart.c
+* Author        : Ryan chen
+*
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+* History      :
+*    1. 2012/09/15 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+
+#if defined(CONFIG_COLDFIRE)
+#include <asm/sizes.h>
+#include <asm/arch/devs.h>
+#include <asm/arch/platform.h>
+#include <asm/arch/irqs.h>
+#else
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <mach/hardware.h>
+#include <plat/ast-scu.h>
+#include <plat/devs.h>
+#endif
+
+/* --------------------------------------------------------------------
+ * UART
+ * -------------------------------------------------------------------- */
+#ifdef CONFIG_SERIAL_8250
+static struct plat_serial8250_port ast_uart_data[] = {
+	{
+		.mapbase	= AST_UART0_BASE,
+		.irq		= IRQ_UART0,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+#if defined(CONFIG_COLDFIRE)		
+		.iotype		= UPIO_MEM32,
+#else
+		.iotype		= UPIO_MEM,
+#endif		
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+	},
+#if defined(CONFIG_ARCH_AST1010)	
+	{
+		.mapbase	= AST_UART1_BASE,
+		.irq		= IRQ_UART1,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype		= UPIO_MEM32,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+	},	
+	{
+		.mapbase	= AST_UART2_BASE,
+		.irq		= IRQ_UART2,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype 	= UPIO_MEM32,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+	},	
+#else
+//BMC UART 1 ,2 default to LPC
+#ifdef CONFIG_ARCH_AST1070
+#ifdef AST_UART1_BASE
+	{
+		.mapbase	= AST_UART1_BASE,
+		.irq		= IRQ_UART1,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+	},	
+#endif
+#ifdef AST_UART2_BASE
+	{
+		.mapbase	= AST_UART2_BASE,
+		.irq		= IRQ_UART2,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+	},	
+#endif
+#endif
+#ifdef AST_UART3_BASE
+	{
+		.mapbase	= AST_UART3_BASE,
+		.irq		= IRQ_UART3,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+	},	
+#endif
+#ifdef AST_UART4_BASE
+	{
+		.mapbase	= AST_UART4_BASE,
+		.irq		= IRQ_UART4,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype 	= UPIO_MEM,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+	},	
+#endif
+#endif	
+	{ },
+};
+
+struct platform_device ast_uart_device = {
+	.name		= "serial8250",
+	.id		= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= ast_uart_data,
+	},
+};
+
+void __init ast_add_device_uart(void)
+{
+#if defined(CONFIG_ARCH_AST1010)
+#else
+	ast_scu_multi_func_uart(3);		
+	ast_scu_multi_func_uart(4);	
+#endif	
+	platform_device_register(&ast_uart_device);
+}
+#else
+void __init ast_add_device_uart(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-uhci.c b/arch/arm/plat-aspeed/dev-uhci.c
new file mode 100644
index 0000000..961ec9b
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-uhci.c
@@ -0,0 +1,82 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-uhci.c
+* Author        : Ryan chen
+* Description   : ASPEED EHCI Device
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2012/07/30 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+
+/* --------------------------------------------------------------------
+ *  UHCI
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_AST_USB_UHCI_HCD) || defined(CONFIG_AST_USB_UHCI_HCD_MODULE)
+static struct resource ast_uchi_resource[] = {
+	[0] = {
+		.start = AST_UHCI_BASE,
+		.end = AST_UHCI_BASE + SZ_256,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_UHCI,
+		.end = IRQ_UHCI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ast_uhci_dma_mask = 0xffffffffUL;
+
+static struct platform_device ast_uhci_device = {
+	.name	= "ast_uhci",
+    .id = 0,
+    .dev = {
+            .dma_mask = &ast_uhci_dma_mask,
+            .coherent_dma_mask = 0xffffffff,
+    },
+	.resource = ast_uchi_resource,
+	.num_resources = ARRAY_SIZE(ast_uchi_resource),
+};
+
+void __init ast_add_device_uhci(void)
+{
+
+#if defined (CONFIG_AST_USB_UHCI_MULTIPORT_2)
+	ast_scu_multi_func_usb11_host_port2(1);
+#elif defined (CONFIG_AST_USB_UHCI_MULTIPORT_4)
+	ast_scu_multi_func_usb11_host_port2(1);
+	ast_scu_multi_func_usb11_host_port4(1);
+#else
+	ast_scu_multi_func_usb11_host_port2(0);
+	ast_scu_multi_func_usb11_host_port4(0);
+#endif
+
+	ast_scu_init_uhci();
+
+	platform_device_register(&ast_uhci_device);
+}
+#else
+void __init ast_add_device_uhci(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-video.c b/arch/arm/plat-aspeed/dev-video.c
new file mode 100644
index 0000000..3d66eff
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-video.c
@@ -0,0 +1,102 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-video.c
+* Author        : Ryan Chen
+* Description   : ASPEED Video Driver
+*
+* Copyright (C) ASPEED Tech. 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
+
+*   History      :
+*    1. 2013/04/15 Ryan Chen initial
+*
+********************************************************************************/
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+
+#include <plat/devs.h>
+#include <plat/ast-scu.h>
+#include <plat/ast-sdmc.h>
+
+#include <mach/ast_video.h>
+
+/* --------------------------------------------------------------------
+ *  AST VIDEO
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_AST_VIDEO) || defined(CONFIG_AST_VIDEO_MODULE)
+
+#define ASR_VIDEO_MEM				AST_DRAM_BASE + SZ_8M*10
+static u32 get_vga_mem_base(void)
+{
+	u32 vga_mem_size, mem_size;
+	mem_size = ast_sdmc_get_mem_size();
+	vga_mem_size = ast_scu_get_vga_memsize();
+	printk("VGA Info : MEM Size %d, VGA Mem Size %d \n",mem_size, vga_mem_size);
+	return (mem_size - vga_mem_size);
+}
+
+static struct ast_video_plat_data video_plat_data = {
+	.get_clk = ast_get_m_pll_clk,
+	.ctrl_reset = ast_scu_reset_video,
+	.vga_display = ast_scu_set_vga_display,
+	.get_vga_base = get_vga_mem_base,
+	.input_source = VIDEO_SOURCE_INTERNAL,
+	.mode = VIDEO_FRAME_MODE,
+	.rc4_enable = 0,
+	.compress = VIDEO_YUV444,
+	.scaling = 0,
+};
+
+
+static struct resource ast_video_resources[] = {
+	[0] = {
+		.start = AST_VIDEO_BASE,
+		.end = AST_VIDEO_BASE + SZ_1K*2 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_VIDEO,
+		.end = IRQ_VIDEO,
+		.flags = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start = ASR_VIDEO_MEM,
+		.end = ASR_VIDEO_MEM + SZ_32M,
+		.flags = IORESOURCE_DMA,
+	},	
+};
+
+static u64 ast_device_video_dmamask = 0xffffffffUL;
+struct platform_device ast_video_device = {
+	.name		  = "ast-video",
+	.id		  = 0,
+	.dev		= {
+		.dma_mask		= &ast_device_video_dmamask,
+		.coherent_dma_mask	= 0xffffffffUL,
+		.platform_data= &video_plat_data,
+	},
+	.resource	= ast_video_resources,
+	.num_resources	= ARRAY_SIZE(ast_video_resources),
+};
+
+void __init ast_add_device_video(void)
+{
+	ast_scu_init_video(0);
+	ast_scu_multi_func_video();
+	platform_device_register(&ast_video_device);
+}
+#else
+void __init ast_add_device_video(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-vuart.c b/arch/arm/plat-aspeed/dev-vuart.c
new file mode 100644
index 0000000..0e2ab8a
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-vuart.c
@@ -0,0 +1,100 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-uart.c
+* Author        : Ryan chen
+*
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+* History      :
+*    1. 2012/09/15 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+#include <mach/hardware.h>
+#include <asm/io.h>
+
+#include <plat/ast-scu.h>
+#include <plat/devs.h>
+
+#include <plat/regs-vuart.h>
+
+#define AST_COM_PORT		PORT_3F8
+#define AST_SIRQ			SIRQ4
+
+#define PORT_2F8		0x2f8
+#define PORT_3F8		0x3f8
+
+typedef enum SIO_serial_irq {
+	SIRQ0 = 0,
+    SIRQ1,
+    SIRQ2,
+    SIRQ3,
+	SIRQ4,
+	SIRQ5,
+	SIRQ6,
+	SIRQ7,
+	SIRQ8,
+	SIRQ9,
+};
+
+/* --------------------------------------------------------------------
+ * UART
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_AST_VUART)
+static struct plat_serial8250_port ast_vuart_data[] = {
+	{
+		.mapbase	= AST_VUART0_BASE,
+		.membase	= (char*)(IO_ADDRESS(AST_VUART0_BASE)),
+		.irq		= IRQ_LPC,
+		.uartclk	= (24*1000000L),
+		.regshift	= 2,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ,
+	},
+	{ },
+};
+
+struct platform_device ast_vuart_device = {
+	.name		= "serial8250",
+	.id		= PLAT8250_DEV_PLATFORM1,
+	.dev			= {
+		.platform_data	= ast_vuart_data,
+	},
+};
+
+void __init ast_add_device_vuart(void)
+{
+	u32 vuart_base = ioremap(AST_VUART0_BASE, SZ_256);
+
+	writel(0x0, vuart_base + AST_VUART_CTRLA);		
+	writel(SET_SIRQ_NUM(AST_SIRQ) |0x3, vuart_base + AST_VUART_CTRLB);
+	writel(AST_COM_PORT & 0xff, vuart_base + AST_VUART_ADDRL);
+	writel(AST_COM_PORT >> 8, vuart_base + AST_VUART_ADDRH);
+	writel(0x0, vuart_base + AST_VUART_CTRLF);
+	writel(VUART_ENABLE | VUART_SIRQ_POLARITY | VUART_DISABLE_H_TX_DISCARD, vuart_base + AST_VUART_CTRLA);	
+
+	iounmap(vuart_base);
+	platform_device_register(&ast_vuart_device);
+}
+#else
+void __init ast_add_device_vuart(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/dev-wdt.c b/arch/arm/plat-aspeed/dev-wdt.c
new file mode 100644
index 0000000..079d1a9
--- /dev/null
+++ b/arch/arm/plat-aspeed/dev-wdt.c
@@ -0,0 +1,76 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/dev-wdt.c
+* Author        : Ryan Chen
+* Description   : AST WDT Device
+*
+* Copyright (C)  ASPEED Technology 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
+
+*   History      :
+*    1. 2012/09/15 Ryan Chen initial
+*
+********************************************************************************/
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/platform.h>
+
+#include <plat/devs.h>
+
+/* --------------------------------------------------------------------
+ *  Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AST_WATCHDOG) || defined(CONFIG_AST_WATCHDOG_MODULE)
+
+static struct resource ast_wdt_resource0[] = {
+	[0] = {
+		.start	= AST_WDT_BASE,
+		.end	= AST_WDT_BASE + (SZ_16*2) - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+			.start = IRQ_WDT,
+			.end = IRQ_WDT,
+			.flags = IORESOURCE_IRQ,
+	},	
+};
+
+static struct resource ast_wdt_resource1[] = {
+	[0] = {
+		.start	= AST_WDT_BASE + (SZ_16*2),
+		.end	= AST_WDT_BASE + (SZ_16*4) - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+			.start = IRQ_WDT,
+			.end = IRQ_WDT,
+			.flags = IORESOURCE_IRQ,
+	},	
+};
+
+static struct platform_device ast_device_wdt = {
+	.name		= "ast-wdt",
+	.id		= -1,
+	.resource       = ast_wdt_resource0,
+	.num_resources  = ARRAY_SIZE(ast_wdt_resource0),
+};
+
+void __init ast_add_device_watchdog(void)
+{
+	platform_device_register(&ast_device_wdt);
+}
+#else
+void __init ast_add_device_watchdog(void) {}
+#endif
diff --git a/arch/arm/plat-aspeed/devs.c b/arch/arm/plat-aspeed/devs.c
new file mode 100644
index 0000000..7906b9c
--- /dev/null
+++ b/arch/arm/plat-aspeed/devs.c
@@ -0,0 +1,69 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/devs.c
+* Author        : Ryan chen
+*
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+* History      :
+*    1. 2012/08/10 create this file [Ryan Chen]
+*
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/platform.h>
+
+#include <plat/devs.h>
+
+typedef void (init_fnc_t) (void);
+
+init_fnc_t __initdata *init_all_device[] = {
+	ast_add_device_uart,
+	ast_add_device_vuart,	
+	ast_add_device_watchdog,
+	ast_add_device_rtc,	
+	ast_add_device_i2c,
+	ast_add_device_spi,
+	ast_add_device_ehci,
+	ast_add_device_nand,
+	ast_add_device_flash,
+	ast_add_device_pwm_fan,
+	ast_add_device_adc,
+	ast_add_device_gpio,		
+	ast_add_device_sgpio,			
+	ast_add_device_peci,	
+	ast_add_device_fb,
+	ast_add_device_sdhci,
+	ast_add_device_uhci,
+	ast_add_device_video,		
+	ast_add_device_kcs,
+	ast_add_device_mailbox,
+	ast_add_device_snoop,
+	ast_add_device_gmac,
+//	ast_add_device_nand,
+	NULL,
+};
+
+void __init ast_add_all_devices(void)
+{
+	init_fnc_t **init_fnc_ptr;
+
+	for (init_fnc_ptr = init_all_device; *init_fnc_ptr; ++init_fnc_ptr) {
+		(*init_fnc_ptr)();
+	}
+
+	return;
+}
diff --git a/arch/arm/plat-aspeed/i2c-slave-eeprom.c b/arch/arm/plat-aspeed/i2c-slave-eeprom.c
new file mode 100644
index 0000000..fd53f1a
--- /dev/null
+++ b/arch/arm/plat-aspeed/i2c-slave-eeprom.c
@@ -0,0 +1,141 @@
+/********************************************************************************
+* File Name     : linux/arch/arm/plat-aspeed/i2c-slave-eeprom.c
+* Author        : Ryan chen
+* Description   : ASPEED I2C Device
+*
+* Copyright (C) ASPEED Technology 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
+
+* History      :
+*    1. 2013/05/30 ryan chen create this file
+*
+********************************************************************************/
+#include <linux/i2c.h>
+#if defined(CONFIG_COLDFIRE)
+#include <asm/arch/ast_i2c.h>
+#else
+#include <plat/ast_i2c.h>
+#endif
+
+#ifdef I2C_EEPROM
+#define EEPROM_DBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
+#else
+#define EEPROM_DBUG(fmt, args...)
+#endif
+
+static u8 cmd_buf[1] = {0};
+static struct i2c_msg cmd_msg = {
+	.addr = 0x04,
+	.len = 1,
+	.buf = cmd_buf,
+};
+
+//Note 10 byte data memory share for all bus slave device ...........
+#define BUF_SIZE 		10
+	
+static u8 store_memory[BUF_SIZE] = {0x03,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
+						//	RO,     RW, .................
+static struct i2c_msg data_msg = {
+	.addr = 0x04,
+	.len = BUF_SIZE,
+	.buf = store_memory,
+};
+static u8 mem_index = 0;
+static u8 slave_stage = INIT_STAGE;
+
+extern void i2c_slave_init(struct i2c_msg **msgs)
+{
+	*msgs = &cmd_msg;
+}
+
+extern void i2c_slave_xfer(i2c_slave_event_t event, struct i2c_msg **msgs)
+{
+	EEPROM_DBUG("[event %d] \n",event);
+	switch(event) {
+		case I2C_SLAVE_EVENT_START_READ:
+			cmd_msg.flags = I2C_M_RD;
+			data_msg.flags = I2C_M_RD;
+			if(slave_stage == INIT_STAGE) {
+				EEPROM_DBUG("Rt DATA_MSG [%x]\n",data_msg.buf[0]);
+				slave_stage = DATA_STAGE;
+				*msgs = &data_msg;
+			} else {
+				//CMD_STAGE
+				if(cmd_msg.buf[0] != ((cmd_msg.addr << 1)|1))
+					printk("START READ ADDR Error %x\n",cmd_msg.buf[0]);
+				
+				EEPROM_DBUG("Rt CMD_DATA_MSG data [%x]\n",store_memory[mem_index]);
+				cmd_msg.buf[0] = store_memory[mem_index];
+				mem_index++;
+				mem_index %=BUF_SIZE;					
+				slave_stage = CMD_DATA_STAGE;
+				*msgs = &cmd_msg;
+			}
+			break;
+		case I2C_SLAVE_EVENT_START_WRITE:
+			EEPROM_DBUG("Rt CMD_MSG START_WRITE %x\n",cmd_msg.buf[0]);
+			cmd_msg.flags = 0;
+			if(cmd_msg.buf[0] != cmd_msg.addr <<1)
+				printk("ERROR ADDRESS Match [%x] \n", cmd_msg.buf[0]);
+			slave_stage = CMD_STAGE;
+			
+			*msgs = &cmd_msg;
+			
+			break;
+				
+		case I2C_SLAVE_EVENT_WRITE:
+			cmd_msg.flags = 0;
+			if(slave_stage == CMD_STAGE) {
+				EEPROM_DBUG("w CMD = [index %x] \n",cmd_msg.buf[0]);
+				mem_index = cmd_msg.buf[0];				
+				mem_index %= BUF_SIZE;
+				slave_stage = CMD_DATA_STAGE;
+				*msgs = &cmd_msg;
+			} else {
+				EEPROM_DBUG("w index %d CMD_DATA [%x] \n",mem_index, cmd_msg.buf[0]);
+				if(mem_index !=0)
+					store_memory[mem_index] = cmd_msg.buf[0];
+				mem_index++;
+				mem_index %=BUF_SIZE;	
+				EEPROM_DBUG("Rt CMD_DATA_MSG \n");
+				*msgs = &cmd_msg;
+			}
+			break;
+		case I2C_SLAVE_EVENT_READ:
+			cmd_msg.flags = I2C_M_RD;			
+			if(slave_stage == CMD_DATA_STAGE) {
+				cmd_msg.buf[0] = store_memory[mem_index];
+				mem_index++;
+				mem_index %=BUF_SIZE;					
+				EEPROM_DBUG("Rt CMD_DATA_MSG [%x]\n",cmd_msg.buf[0]);		
+				*msgs = &cmd_msg;
+			} else {
+				EEPROM_DBUG("Rt DATA_MSG [%x]\n",data_msg.buf[0]);		
+				*msgs = &data_msg;
+			}			
+			break;
+		case I2C_SLAVE_EVENT_NACK:
+			cmd_msg.flags = I2C_M_RD;			
+			slave_stage = INIT_STAGE;
+			*msgs = &cmd_msg;
+
+			break;
+			
+		case I2C_SLAVE_EVENT_STOP:
+			cmd_msg.flags = I2C_M_RD;			
+			slave_stage = INIT_STAGE;
+			*msgs = &cmd_msg;
+			break;
+	}
+
+}
diff --git a/arch/arm/plat-aspeed/include/plat/aspeed.h b/arch/arm/plat-aspeed/include/plat/aspeed.h
new file mode 100644
index 0000000..4f7c240
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/aspeed.h
@@ -0,0 +1,44 @@
+/*
+ *  arch/arm/plat-aspeed/include/plat/aspeed.h
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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
+ */
+
+#if defined(CONFIG_ARCH_AST3200) || defined(CONFIG_ARCH_AST2500) || defined(CONFIG_ARCH_AST1520)
+#define AST_SOC_G5
+#define NEW_VIC
+#define SRAM_SIZE 		SZ_32K
+#elif defined(CONFIG_ARCH_AST1400) || defined(CONFIG_ARCH_AST2400) || defined(CONFIG_ARCH_AST3100)
+#define AST_SOC_G4
+#define NEW_VIC
+#define SRAM_SIZE 		SZ_32K
+#elif defined(CONFIG_ARCH_AST1300) || defined(CONFIG_ARCH_AST2300) || defined(CONFIG_ARCH_AST1510)
+#define AST_SOC_G3
+#define NEW_VIC
+#define SRAM_SIZE 		SZ_16K
+#elif defined(CONFIG_ARCH_AST2150) || defined(CONFIG_ARCH_AST2200)
+#define AST_SOC_G2_5
+#elif defined(CONFIG_ARCH_AST1100) || defined(CONFIG_ARCH_AST2050) || defined(CONFIG_ARCH_AST2100)
+#define AST_SOC_G2
+#elif defined(CONFIG_ARCH_AST2000) || defined(CONFIG_ARCH_AST1000)
+#define AST_SOC_G1
+#else
+#error "Not define SoC generation"
+#endif
+
+
+
diff --git a/arch/arm/plat-aspeed/include/plat/ast-lpc.h b/arch/arm/plat-aspeed/include/plat/ast-lpc.h
new file mode 100644
index 0000000..1bf2bef
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/ast-lpc.h
@@ -0,0 +1,34 @@
+/*
+ * Platform data for AST LPC .
+ *
+ * Copyright (C) ASPEED Technology 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+struct ast_lpc_bus_info
+{
+	u8 lpc_dev_mode; /* 0: host mode , 1: dev mode*/	
+	u8 bus_scan;
+	u8 scan_node;	
+	u8 lpc_mode; /* 0: lpc , 1: lpc+ */
+	u32 bridge_phy_addr;
+};
+
+struct ast_lpc_driver_data
+{
+	struct platform_device *pdev;
+	void __iomem		*reg_base;			/* virtual */	
+	int 				irq;				//I2C IRQ number 
+	u32					bus_id;				//for i2c dev# IRQ number check 
+	struct ast_lpc_bus_info *bus_info;
+};
+
+extern struct ast_lpc_info *ast_get_lpc_info(void);
diff --git a/arch/arm/plat-aspeed/include/plat/ast-pcie.h b/arch/arm/plat-aspeed/include/plat/ast-pcie.h
new file mode 100644
index 0000000..d099c57
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/ast-pcie.h
@@ -0,0 +1,28 @@
+/*
+ * Platform data for AST PCIe Root Complex module.
+ *
+ * Copyright (C) ASPEED Technology 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __AST_PCIE_H_
+#define __AST_PCIE_H_
+
+struct ast_pcie_data {
+	int msi_irq_base;
+	int msi_irq_num;
+	int force_x1;
+	int msi_inv;		/* 1 = MSI ack requires "write 0 to clear" */
+	unsigned short int device_id;
+};
+
+#endif
+
diff --git a/arch/arm/plat-aspeed/include/plat/ast-scu.h b/arch/arm/plat-aspeed/include/plat/ast-scu.h
new file mode 100644
index 0000000..77169ee
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/ast-scu.h
@@ -0,0 +1,92 @@
+/********************************************************************************
+* File Name     : arch/arm/mach-aspeed/include/plat/ast-scu.h
+* Author        : Ryan Chen
+* Description   : AST SCU Service Header
+*
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+*   History      :
+*      1. 2012/08/03 Ryan Chen create this file
+*
+********************************************************************************/
+
+#ifndef __AST_SCU_H_INCLUDED
+#define __AST_SCU_H_INCLUDED
+
+//information
+extern void ast_scu_show_system_info (void);
+extern u32 ast_scu_revision_id(void);
+extern u32 ast_scu_get_phy_interface(u8 mac_num);
+extern u32 ast_scu_get_phy_config(u8 mac_num);
+
+
+//CLK 
+extern u32 ast_get_clk_source(void);
+extern u32 ast_get_h_pll_clk(void);
+extern u32 ast_get_m_pll_clk(void);
+extern u32 ast_get_pclk(void);
+extern u32 ast_get_sd_clock_src(void);
+extern u32 ast_get_d2_pll_clk(void);
+extern u32 ast_get_lhclk(void);
+
+extern void ast_scu_set_vga_display(u8 enable);
+extern u32 ast_scu_get_vga_memsize(void);
+
+//Ctrl Initial
+extern void ast_scu_init_video(u8 dynamic_en);
+extern void ast_scu_reset_video(void);
+extern void ast_scu_init_eth(u8 num);
+extern void ast_scu_init_lpc(void);
+extern u8 ast_scu_get_lpc_plus_enable(void);
+extern void ast_scu_init_udc11(void);
+extern void ast_scu_init_usb20(void);
+extern void ast_scu_init_uhci(void);
+extern void ast_scu_init_sdhci(void);
+extern void ast_scu_init_i2c(void);
+extern void ast_scu_init_pwm_tacho(void);
+extern void ast_scu_init_adc(void);
+extern void ast_scu_init_peci(void);
+extern void ast_scu_init_jtag(void);
+extern void ast_scu_init_crt(void);
+
+
+
+//Share pin
+extern void ast_scu_multi_func_uart(u8 uart);
+extern void ast_scu_multi_func_video(void);
+
+extern void ast_scu_multi_func_eth(u8 num);
+
+extern void ast_scu_multi_func_nand(void);
+
+extern void ast_scu_multi_func_nor(void);
+
+extern void ast_scu_multi_func_romcs(u8 num);
+
+extern void ast_scu_multi_func_i2c(void);
+extern void ast_scu_multi_func_pwm_tacho(void);
+//0 : hub mode , 1: usb host mode
+extern void ast_scu_multi_func_usb20_host_hub(u8 mode);
+//0 : gpioQ6,7 mode , 1: usb1.1 host port 4 mode
+extern void ast_scu_multi_func_usb11_host_port4(u8 mode);
+//0 : USB 1.1 HID mode , 1: usb1.1 host port 2 mode
+extern void ast_scu_multi_func_usb11_host_port2(u8 mode);
+
+extern void ast_scu_multi_func_sdhc_slot1(u8 mode);
+extern void ast_scu_multi_func_sdhc_slot2(u8 mode);
+extern void ast_scu_multi_func_crt(void);
+
+
+
+
+
+#endif
diff --git a/arch/arm/plat-aspeed/include/plat/ast-sdmc.h b/arch/arm/plat-aspeed/include/plat/ast-sdmc.h
new file mode 100644
index 0000000..72d8d72
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/ast-sdmc.h
@@ -0,0 +1,26 @@
+/********************************************************************************
+* File Name     : arch/arm/mach-aspeed/include/plat/ast-scu.h
+* Author        : Ryan Chen
+* Description   : AST SCU Service Header
+*
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+*   History      :
+*      1. 2012/08/03 Ryan Chen create this file
+*
+********************************************************************************/
+
+#ifndef __AST_SDMC_H_INCLUDED
+#define __AST_SDMC_H_INCLUDED
+
+extern u32 ast_sdmc_get_mem_size(void);
+#endif
diff --git a/arch/arm/plat-aspeed/include/plat/ast-snoop.h b/arch/arm/plat-aspeed/include/plat/ast-snoop.h
new file mode 100644
index 0000000..76ea7611
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/ast-snoop.h
@@ -0,0 +1,37 @@
+/*
+ *  ast-snoop_h
+ *
+ *
+ * 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.
+ */
+
+struct ast_snoop_channel {
+	u8	snoop_ch;
+	u8	snoop_port;	
+	u8	snoop_data;	
+};
+
+struct ast_snoop {
+	struct ast_snoop_channel	*snoop_ch0;
+	struct ast_snoop_channel	*snoop_ch1;	
+};
+
+struct ast_snoop_dma_channel {
+	u8	snoop_ch;	
+	u8	snoop_port;
+	u8	snoop_mask;
+	u8	snoop_mode;
+	u8	snoop_index;
+	u32	dma_virt;	
+	dma_addr_t dma_addr;	
+	u16 dma_size;
+};
+
+extern int ast_snoop_init(struct ast_snoop *snoop);
+extern void ast_snoop_dma_init(struct ast_snoop_dma_channel *ast_dma_ch);
+
+
+
diff --git a/arch/arm/plat-aspeed/include/plat/ast1070-devs.h b/arch/arm/plat-aspeed/include/plat/ast1070-devs.h
new file mode 100644
index 0000000..b3aa799
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/ast1070-devs.h
@@ -0,0 +1,25 @@
+/********************************************************************************
+* arch/arm/plat-aspeed/include/plat/devs.h
+*
+* Copyright (C) ASPEED Technology 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_PLAT_AST1070_H
+#define __ASM_PLAT_AST1070_H
+
+//ast1070
+extern void __init ast_add_device_cuart(u8 chip, u32 lpc_base);
+extern void __init ast_add_device_clpc(u8 chip, u32 lpc_base);
+extern void __init ast_add_device_ci2c(u8 chip, u32 lpc_base);
+
+#endif
diff --git a/arch/arm/plat-aspeed/include/plat/ast1070-scu.h b/arch/arm/plat-aspeed/include/plat/ast1070-scu.h
new file mode 100644
index 0000000..70c63e2
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/ast1070-scu.h
@@ -0,0 +1,34 @@
+/********************************************************************************
+* File Name     : arch/arm/mach-aspeed/include/plat/ast1070-scu.h
+* Author        : Ryan Chen
+* Description   : AST1070 SCU Service Header
+*
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+*   History      :
+*      1. 2013/05/03 Ryan Chen create this file
+*
+********************************************************************************/
+
+#ifndef __AST1070_SCU_H_INCLUDED
+#define __AST1070_SCU_H_INCLUDED
+
+extern void ast1070_scu_init_i2c(u8 node);
+extern void ast1070_scu_init_uart(u8 node);
+extern void ast1070_scu_revision_id(u8 node);
+extern void ast1070_dma_init(u8 node);
+extern void ast1070_multi_func_uart(u8 node, u8 uart);
+
+
+
+
+#endif
diff --git a/arch/arm/plat-aspeed/include/plat/ast1070-uart-dma.h b/arch/arm/plat-aspeed/include/plat/ast1070-uart-dma.h
new file mode 100644
index 0000000..c4edd75
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/ast1070-uart-dma.h
@@ -0,0 +1,27 @@
+/********************************************************************************
+* File Name     : arch/arm/mach-aspeed/include/plat/ast1070-scu.h
+* Author        : Ryan Chen
+* Description   : AST1070 SCU Service Header
+*
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+*   History      :
+*      1. 2013/05/03 Ryan Chen create this file
+*
+********************************************************************************/
+
+#ifndef __AST1070_UART_DMA_H_INCLUDED
+#define __AST1070_UART_DMA_H_INCLUDED
+
+extern void ast1070_uart_dma_init(u8 node);
+
+#endif
diff --git a/arch/arm/plat-aspeed/include/plat/ast_i2c.h b/arch/arm/plat-aspeed/include/plat/ast_i2c.h
new file mode 100644
index 0000000..b0ff995
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/ast_i2c.h
@@ -0,0 +1,64 @@
+/*
+ *  ast_i2c_h  
+ *
+ *
+ * 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.
+ */
+
+//I2C MEMORY Device state machine
+typedef enum i2c_slave_stage {
+		INIT_STAGE,
+        CMD_STAGE,
+        CMD_DATA_STAGE,
+        DATA_STAGE
+} stage;
+
+typedef enum i2c_xfer_mode {
+        BYTE_XFER,
+        BUFF_XFER,			
+        DMA_XFER
+} i2c_xfer_mode_t;
+
+//1. usage flag , 2 size,	3. request address
+struct buf_page
+{
+	u8 flag; //0:free to usage, 1: used
+	u8 page_no; //for AST2400 usage
+	u16 page_size;
+	u32 page_addr;
+	u32 page_addr_point;
+};
+
+typedef enum i2c_slave_event_e {
+        I2C_SLAVE_EVENT_START_READ,
+        I2C_SLAVE_EVENT_READ,			
+        I2C_SLAVE_EVENT_START_WRITE,
+        I2C_SLAVE_EVENT_WRITE,     
+        I2C_SLAVE_EVENT_NACK,
+        I2C_SLAVE_EVENT_STOP
+} i2c_slave_event_t;
+
+#define BYTE_MODE	0
+#define BUFF_MODE	1
+#define DMA_MODE	2
+
+struct ast_i2c_driver_data {
+		void __iomem		*reg_gr;
+		u32		bus_clk;
+		u8		master_dma;		//0,byte mode 1,Buffer pool mode 256 , or 2048 , 2: DMA mode
+		u8		slave_dma;		//0,byte mode 1,Buffer pool mode 256 , or 2048 , 2: DMA mode
+		u8 		(*request_pool_buff_page)(struct buf_page **page);
+		void 	(*free_pool_buff_page)(struct buf_page *page);
+		unsigned char	*buf_pool;
+		void (*slave_xfer)(i2c_slave_event_t event, struct i2c_msg **msgs);
+		void (*slave_init)(struct i2c_msg **msgs);
+		u32 (*get_i2c_clock)(void);
+};
+
+#ifdef CONFIG_AST_I2C_SLAVE_MODE
+extern void i2c_slave_init(struct i2c_msg **msgs);
+extern void i2c_slave_xfer(i2c_slave_event_t event, struct i2c_msg **msgs);
+#endif
\ No newline at end of file
diff --git a/arch/arm/plat-aspeed/include/plat/ast_mctp.h b/arch/arm/plat-aspeed/include/plat/ast_mctp.h
new file mode 100644
index 0000000..51396ff
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/ast_mctp.h
@@ -0,0 +1,31 @@
+/********************************************************************************
+* File Name     : arch/arm/mach-aspeed/include/plat/ast-scu.h
+* Author        : Ryan Chen
+* Description   : AST SCU Service Header
+*
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+*   History      :
+*      1. 2012/08/03 Ryan Chen create this file
+*
+********************************************************************************/
+
+#ifndef __AST_P2X_H_INCLUDED
+#define __AST_P2X_H_INCLUDED
+
+extern void ast_pcie_cfg_read(u8 type, u32 bdf_offset, u32 *value);
+//extern void ast_pcie_cfg_write(u8 type, u32 bdf_offset, u32 data);
+extern void ast_pcie_cfg_write(u8 type, u8 byte_en, u32 bdf_offset, u32 data);
+extern void ast_mctp_addr_map(u32 mask, u32 addr);
+
+#endif
+
diff --git a/arch/arm/plat-aspeed/include/plat/ast_sdhci.h b/arch/arm/plat-aspeed/include/plat/ast_sdhci.h
new file mode 100644
index 0000000..13547af
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/ast_sdhci.h
@@ -0,0 +1,290 @@
+/*
+ *  sdhci.h - Secure Digital Host Controller Interface driver
+ *
+ * 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.
+ */
+
+#include <linux/scatterlist.h>
+#include <linux/leds.h>
+#include <linux/interrupt.h>
+
+
+/*
+ * Controller registers
+ */
+
+#define SDHCI_DMA_ADDRESS	0x00
+
+#define SDHCI_BLOCK_SIZE	0x04
+#define  SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF))
+
+#define SDHCI_BLOCK_COUNT	0x06
+
+#define SDHCI_ARGUMENT		0x08
+
+#define SDHCI_TRANSFER_MODE	0x0C
+#define  SDHCI_TRNS_DMA		0x01
+#define  SDHCI_TRNS_BLK_CNT_EN	0x02
+#define  SDHCI_TRNS_ACMD12	0x04
+#define  SDHCI_TRNS_READ	0x10
+#define  SDHCI_TRNS_MULTI	0x20
+
+#define SDHCI_COMMAND		0x0E
+#define  SDHCI_CMD_RESP_MASK	0x03
+#define  SDHCI_CMD_CRC		0x08
+#define  SDHCI_CMD_INDEX	0x10
+#define  SDHCI_CMD_DATA		0x20
+
+#define  SDHCI_CMD_RESP_NONE	0x00
+#define  SDHCI_CMD_RESP_LONG	0x01
+#define  SDHCI_CMD_RESP_SHORT	0x02
+#define  SDHCI_CMD_RESP_SHORT_BUSY 0x03
+
+#define SDHCI_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff))
+
+#define SDHCI_RESPONSE		0x10
+
+#define SDHCI_BUFFER		0x20
+
+#define SDHCI_PRESENT_STATE	0x24
+#define  SDHCI_CMD_INHIBIT	0x00000001
+#define  SDHCI_DATA_INHIBIT	0x00000002
+#define  SDHCI_DOING_WRITE	0x00000100
+#define  SDHCI_DOING_READ	0x00000200
+#define  SDHCI_SPACE_AVAILABLE	0x00000400
+#define  SDHCI_DATA_AVAILABLE	0x00000800
+#define  SDHCI_CARD_PRESENT	0x00010000
+#define  SDHCI_WRITE_PROTECT	0x00080000
+
+#define SDHCI_HOST_CONTROL 	0x28
+#define  SDHCI_CTRL_LED		0x01
+#define  SDHCI_CTRL_4BITBUS	0x02
+#define  SDHCI_CTRL_HISPD	0x04
+#define  SDHCI_CTRL_DMA_MASK	0x18
+#define   SDHCI_CTRL_SDMA	0x00
+#define   SDHCI_CTRL_ADMA1	0x08
+#define   SDHCI_CTRL_ADMA32	0x10
+#define   SDHCI_CTRL_ADMA64	0x18
+
+#define SDHCI_POWER_CONTROL	0x29
+#define  SDHCI_POWER_ON		0x01
+#define  SDHCI_POWER_180	0x0A
+#define  SDHCI_POWER_300	0x0C
+#define  SDHCI_POWER_330	0x0E
+
+#define SDHCI_BLOCK_GAP_CONTROL	0x2A
+
+#define SDHCI_WAKE_UP_CONTROL	0x2B
+
+#define SDHCI_CLOCK_CONTROL	0x2C
+#define  SDHCI_DIVIDER_SHIFT	8
+#define  SDHCI_CLOCK_CARD_EN	0x0004
+#define  SDHCI_CLOCK_INT_STABLE	0x0002
+#define  SDHCI_CLOCK_INT_EN	0x0001
+
+#define SDHCI_TIMEOUT_CONTROL	0x2E
+
+#define SDHCI_SOFTWARE_RESET	0x2F
+#define  SDHCI_RESET_ALL	0x01
+#define  SDHCI_RESET_CMD	0x02
+#define  SDHCI_RESET_DATA	0x04
+
+#define SDHCI_INT_STATUS	0x30
+#define SDHCI_INT_ENABLE	0x34
+#define SDHCI_SIGNAL_ENABLE	0x38
+#define  SDHCI_INT_RESPONSE	0x00000001
+#define  SDHCI_INT_DATA_END	0x00000002
+#define  SDHCI_INT_DMA_END	0x00000008
+#define  SDHCI_INT_SPACE_AVAIL	0x00000010
+#define  SDHCI_INT_DATA_AVAIL	0x00000020
+#define  SDHCI_INT_CARD_INSERT	0x00000040
+#define  SDHCI_INT_CARD_REMOVE	0x00000080
+#define  SDHCI_INT_CARD_INT	0x00000100
+#define  SDHCI_INT_ERROR	0x00008000
+#define  SDHCI_INT_TIMEOUT	0x00010000
+#define  SDHCI_INT_CRC		0x00020000
+#define  SDHCI_INT_END_BIT	0x00040000
+#define  SDHCI_INT_INDEX	0x00080000
+#define  SDHCI_INT_DATA_TIMEOUT	0x00100000
+#define  SDHCI_INT_DATA_CRC	0x00200000
+#define  SDHCI_INT_DATA_END_BIT	0x00400000
+#define  SDHCI_INT_BUS_POWER	0x00800000
+#define  SDHCI_INT_ACMD12ERR	0x01000000
+#define  SDHCI_INT_ADMA_ERROR	0x02000000
+
+#define  SDHCI_INT_NORMAL_MASK	0x00007FFF
+#define  SDHCI_INT_ERROR_MASK	0xFFFF8000
+
+#define  SDHCI_INT_CMD_MASK	(SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \
+		SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX)
+#define  SDHCI_INT_DATA_MASK	(SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \
+		SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
+		SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
+		SDHCI_INT_DATA_END_BIT)
+
+#define SDHCI_ACMD12_ERR	0x3C
+
+/* 3E-3F reserved */
+
+#define SDHCI_CAPABILITIES	0x40
+#define  SDHCI_TIMEOUT_CLK_MASK	0x0000003F
+#define  SDHCI_TIMEOUT_CLK_SHIFT 0
+#define  SDHCI_TIMEOUT_CLK_UNIT	0x00000080
+#define  SDHCI_CLOCK_BASE_MASK	0x00003F00
+#define  SDHCI_CLOCK_BASE_SHIFT	8
+#define  SDHCI_MAX_BLOCK_MASK	0x00030000
+#define  SDHCI_MAX_BLOCK_SHIFT  16
+#define  SDHCI_CAN_DO_ADMA2	0x00080000
+#define  SDHCI_CAN_DO_ADMA1	0x00100000
+#define  SDHCI_CAN_DO_HISPD	0x00200000
+#define  SDHCI_CAN_DO_DMA	0x00400000
+#define  SDHCI_CAN_VDD_330	0x01000000
+#define  SDHCI_CAN_VDD_300	0x02000000
+#define  SDHCI_CAN_VDD_180	0x04000000
+#define  SDHCI_CAN_64BIT	0x10000000
+
+/* 44-47 reserved for more caps */
+
+#define SDHCI_MAX_CURRENT	0x48
+
+/* 4C-4F reserved for more max current */
+
+#define SDHCI_SET_ACMD12_ERROR	0x50
+#define SDHCI_SET_INT_ERROR	0x52
+
+#define SDHCI_ADMA_ERROR	0x54
+
+/* 55-57 reserved */
+
+#define SDHCI_ADMA_ADDRESS	0x58
+
+/* 60-FB reserved */
+
+#define SDHCI_SLOT_INT_STATUS	0xFC
+
+#define SDHCI_HOST_VERSION	0xFE
+#define  SDHCI_VENDOR_VER_MASK	0xFF00
+#define  SDHCI_VENDOR_VER_SHIFT	8
+#define  SDHCI_SPEC_VER_MASK	0x00FF
+#define  SDHCI_SPEC_VER_SHIFT	0
+#define   SDHCI_SPEC_100	0
+#define   SDHCI_SPEC_200	1
+
+struct sdhci_ops;
+
+struct sdhci_host {
+	/* Data set by hardware interface driver */
+	const char		*hw_name;	/* Hardware bus name */
+
+	unsigned int		quirks;		/* Deviations from spec. */
+
+/* Controller doesn't honor resets unless we touch the clock register */
+#define SDHCI_QUIRK_CLOCK_BEFORE_RESET			(1<<0)
+/* Controller has bad caps bits, but really supports DMA */
+#define SDHCI_QUIRK_FORCE_DMA				(1<<1)
+/* Controller doesn't like to be reset when there is no card inserted. */
+#define SDHCI_QUIRK_NO_CARD_NO_RESET			(1<<2)
+/* Controller doesn't like clearing the power reg before a change */
+#define SDHCI_QUIRK_SINGLE_POWER_WRITE			(1<<3)
+/* Controller has flaky internal state so reset it on each ios change */
+#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS		(1<<4)
+/* Controller has an unusable DMA engine */
+#define SDHCI_QUIRK_BROKEN_DMA				(1<<5)
+/* Controller has an unusable ADMA engine */
+#define SDHCI_QUIRK_BROKEN_ADMA				(1<<6)
+/* Controller can only DMA from 32-bit aligned addresses */
+#define SDHCI_QUIRK_32BIT_DMA_ADDR			(1<<7)
+/* Controller can only DMA chunk sizes that are a multiple of 32 bits */
+#define SDHCI_QUIRK_32BIT_DMA_SIZE			(1<<8)
+/* Controller can only ADMA chunks that are a multiple of 32 bits */
+#define SDHCI_QUIRK_32BIT_ADMA_SIZE			(1<<9)
+/* Controller needs to be reset after each request to stay stable */
+#define SDHCI_QUIRK_RESET_AFTER_REQUEST			(1<<10)
+/* Controller needs voltage and power writes to happen separately */
+#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER		(1<<11)
+/* Controller provides an incorrect timeout value for transfers */
+#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL			(1<<12)
+/* Controller has an issue with buffer bits for small transfers */
+#define SDHCI_QUIRK_BROKEN_SMALL_PIO			(1<<13)
+/* Controller supports high speed but doesn't have the caps bit set */
+#define SDHCI_QUIRK_FORCE_HIGHSPEED			(1<<14)
+/* Controller does not provide transfer-complete interrupt when not busy */
+#define SDHCI_QUIRK_NO_BUSY_IRQ				(1<<15)
+
+	int			irq;		/* Device IRQ */
+	void __iomem *		ioaddr;		/* Mapped address */
+
+	const struct sdhci_ops	*ops;		/* Low level hw interface */
+
+	/* Internal data */
+	struct mmc_host		*mmc;		/* MMC structure */
+	u64			dma_mask;	/* custom DMA mask */
+
+#ifdef CONFIG_LEDS_CLASS
+	struct led_classdev	led;		/* LED control */
+	char   led_name[32];
+#endif
+
+	spinlock_t		lock;		/* Mutex */
+
+	int			flags;		/* Host attributes */
+#define SDHCI_USE_DMA		(1<<0)		/* Host is DMA capable */
+#define SDHCI_USE_ADMA		(1<<1)		/* Host is ADMA capable */
+#define SDHCI_REQ_USE_DMA	(1<<2)		/* Use DMA for this req. */
+#define SDHCI_DEVICE_DEAD	(1<<3)		/* Device unresponsive */
+
+	unsigned int		version;	/* SDHCI spec. version */
+
+	unsigned int		max_clk;	/* Max possible freq (MHz) */
+	unsigned int		timeout_clk;	/* Timeout freq (KHz) */
+
+	unsigned int		clock;		/* Current clock (MHz) */
+	unsigned short		power;		/* Current voltage */
+
+	struct mmc_request	*mrq;		/* Current request */
+	struct mmc_command	*cmd;		/* Current command */
+	struct mmc_data		*data;		/* Current data request */
+	unsigned int		data_early:1;	/* Data finished before cmd */
+
+	struct sg_mapping_iter	sg_miter;	/* SG state for PIO */
+	unsigned int		blocks;		/* remaining PIO blocks */
+
+	int			sg_count;	/* Mapped sg entries */
+
+	u8			*adma_desc;	/* ADMA descriptor table */
+	u8			*align_buffer;	/* Bounce buffer */
+
+	dma_addr_t		adma_addr;	/* Mapped ADMA descr. table */
+	dma_addr_t		align_addr;	/* Mapped bounce buffer */
+
+	struct tasklet_struct	card_tasklet;	/* Tasklet structures */
+	struct tasklet_struct	finish_tasklet;
+
+	struct timer_list	timer;		/* Timer for timeouts */
+
+	unsigned long		private[0] ____cacheline_aligned;
+};
+
+struct ast_sdhc_platform_data {
+        u32     (*sd_clock_src_get)(void);
+};
+
+extern struct sdhci_host *sdhci_alloc_host(struct device *dev,
+	size_t priv_size);
+extern void sdhci_free_host(struct sdhci_host *host);
+
+static inline void *sdhci_priv(struct sdhci_host *host)
+{
+	return (void *)host->private;
+}
+
+extern int sdhci_add_host(struct sdhci_host *host);
+extern void sdhci_remove_host(struct sdhci_host *host, int dead);
+
+#ifdef CONFIG_PM
+extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state);
+extern int sdhci_resume_host(struct sdhci_host *host);
+#endif
diff --git a/arch/arm/plat-aspeed/include/plat/devs.h b/arch/arm/plat-aspeed/include/plat/devs.h
new file mode 100644
index 0000000..41cbea9
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/devs.h
@@ -0,0 +1,65 @@
+/********************************************************************************
+* arch/arm/plat-aspeed/include/plat/devs.h
+*
+* Copyright (C) ASPEED Technology 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_PLAT_ASPEED_H
+#define __ASM_PLAT_ASPEED_H
+
+extern void __init ast_add_all_devices(void);
+
+//platform
+extern void __init ast_add_device_uart(void);
+extern void __init ast_add_device_vuart(void);
+extern void __init ast_add_device_watchdog(void);
+extern void __init ast_add_device_rtc(void);
+extern void __init ast_add_device_gpio(void);
+extern void __init ast_add_device_sgpio(void);
+
+//ADC 
+
+//Bus
+extern void __init ast_add_device_lpc(void);
+extern void __init ast_add_device_snoop(void);
+extern void __init ast_add_device_kcs(void);
+extern void __init ast_add_device_mailbox(void);
+extern void __init ast_add_device_i2c(void);
+extern void __init ast_add_device_spi(void);
+extern void __init ast_add_device_ehci(void);
+extern void __init ast_add_device_uhci(void);
+extern void __init ast_add_device_gmac(void);
+extern void __init ast_add_device_udc11(void);
+extern void __init ast_add_device_hid(void);
+
+extern void __init ast_add_device_pcie(void);
+
+extern void __init ast_add_device_peci(void);
+extern void __init ast_add_device_jtag(void);
+
+//hwmon
+extern void __init ast_add_device_pwm_fan(void);
+extern void __init ast_add_device_adc(void);
+
+
+//Storage
+extern void __init ast_add_device_nand(void);
+extern void __init ast_add_device_flash(void);
+extern void __init ast_add_device_sdhci(void);
+extern void __init ast_add_device_nand(void);
+
+//video
+extern void __init ast_add_device_fb(void);
+extern void __init ast_add_device_video(void);
+
+#endif
diff --git a/arch/arm/plat-aspeed/include/plat/regs-1070_lpc.h b/arch/arm/plat-aspeed/include/plat/regs-1070_lpc.h
new file mode 100644
index 0000000..ef8cd8c
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-1070_lpc.h
@@ -0,0 +1,32 @@
+/* arch/arm/plat-aspeed/include/mach/regs-1070_lpc.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED AST1070 LPC Controller
+*/
+
+#ifndef __ASM_ARCH_REGS_LPC_H
+#define __ASM_ARCH_REGS_LPC_H __FILE__
+
+#define AST1070_LPC_HICR0			0x00
+#define AST1070_LPC_HICR1			0x04
+#define AST1070_LPC_HICR2			0x08
+#define AST1070_LPC_HICR3			0x0c
+#define AST1070_LPC_HICR4			0x10
+
+//for snoop driver 
+#define AST1070_LPC_L_80H_ADDR		0x220
+#define AST1070_LPC_H_80H_ADDR		0x224
+#define AST1070_LPC_80H_DATA		0x228
+#define AST1070_LPC_80H_CTRL		0x22c
+
+
+#define AST1070_LPC_80H_CLR			(0x1 << 4)
+
+#define AST1070_LPC_80H_EN			0x1
+#endif /* __ASM_ARCH_REGS_LPC_H */
diff --git a/arch/arm/plat-aspeed/include/plat/regs-adc.h b/arch/arm/plat-aspeed/include/plat/regs-adc.h
new file mode 100644
index 0000000..97f5919
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-adc.h
@@ -0,0 +1,191 @@
+/* arch/arm/plat-aspeed/include/mach/regs-adc.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED ADC Controller
+*/
+
+#ifndef __ASM_ARCH_REGS_ADC_H
+#define __ASM_ARCH_REGS_ADC_H __FILE__
+
+#if defined(CONFIG_ARCH_AST2300)
+#define MAX_CH_NO		12
+#elif defined(CONFIG_ARCH_AST2400) || defined(CONFIG_ARCH_AST2500) 
+#define MAX_CH_NO		16
+#elif defined(CONFIG_ARCH_AST1010)
+#define MAX_CH_NO		8
+#else
+#err "ADC NO define MAX CHANNEL NO"
+#endif
+
+#if defined(CONFIG_ARCH_AST2500) 
+#define TEMPER_CH_NO	2
+#endif
+
+/*AST ADC Register Definition */
+#define AST_ADC_CTRL			0x00
+#define AST_ADC_IER				0x04
+#define AST_ADC_VGA				0x08
+#if defined(CONFIG_ARCH_AST1010)
+#define AST_ADC_TRIM			0x08
+#endif
+#define AST_ADC_CLK				0x0c
+#define AST_ADC_CH0_1			0x10
+#define AST_ADC_CH2_3			0x14
+#define AST_ADC_CH4_5			0x18
+#define AST_ADC_CH6_7			0x1c
+#define AST_ADC_CH8_9			0x20
+#define AST_ADC_CH10_11			0x24
+#define AST_ADC_CH12_13			0x28
+#define AST_ADC_CH14_15			0x2c
+#define AST_ADC_BOUND0			0x30
+#define AST_ADC_BOUND1			0x34
+#define AST_ADC_BOUND2			0x38
+#define AST_ADC_BOUND3			0x3c
+#define AST_ADC_BOUND4			0x40
+#define AST_ADC_BOUND5			0x44
+#define AST_ADC_BOUND6			0x48
+#define AST_ADC_BOUND7			0x4c
+#define AST_ADC_BOUND8			0x50
+#define AST_ADC_BOUND9			0x54
+#define AST_ADC_BOUND10			0x58
+#define AST_ADC_BOUND11			0x5c
+#define AST_ADC_BOUND12			0x60
+#define AST_ADC_BOUND13			0x64
+#define AST_ADC_BOUND14			0x68
+#define AST_ADC_BOUND15			0x6c
+#define AST_ADC_HYSTER0			0x70
+#define AST_ADC_HYSTER1			0x74
+#define AST_ADC_HYSTER2			0x78
+#define AST_ADC_HYSTER3			0x7c
+#define AST_ADC_HYSTER4			0x80
+#define AST_ADC_HYSTER5			0x84
+#define AST_ADC_HYSTER6			0x88
+#define AST_ADC_HYSTER7			0x8c
+#define AST_ADC_HYSTER8			0x90
+#define AST_ADC_HYSTER9			0x94
+#define AST_ADC_HYSTER10		0x98
+#define AST_ADC_HYSTER11		0x9c
+#define AST_ADC_HYSTER12		0xa0
+#define AST_ADC_HYSTER13		0xa4
+#define AST_ADC_HYSTER14		0xa8
+#define AST_ADC_HYSTER15		0xac
+#define AST_ADC_INTR_SEL		0xC0
+#if defined(CONFIG_ARCH_AST2500)
+#define AST_ADC_CH16			0xD0
+#define AST_ADC_CH17			0xD4
+#endif
+
+
+#define AST_ADC_TRIM			0xC4
+
+// AST_ADC_CTRL:0x00 - ADC Engine Control Register 
+#define AST_ADC_CTRL_CH15_EN		(0x1 << 31)
+#define AST_ADC_CTRL_CH14_EN		(0x1 << 30)
+#define AST_ADC_CTRL_CH13_EN		(0x1 << 29)
+#define AST_ADC_CTRL_CH12_EN		(0x1 << 28)
+#define AST_ADC_CTRL_CH11_EN		(0x1 << 27)
+#define AST_ADC_CTRL_CH10_EN		(0x1 << 26)
+#define AST_ADC_CTRL_CH9_EN			(0x1 << 25)
+#define AST_ADC_CTRL_CH8_EN			(0x1 << 24)
+#define AST_ADC_CTRL_CH7_EN			(0x1 << 23)
+#define AST_ADC_CTRL_CH6_EN			(0x1 << 22)
+#define AST_ADC_CTRL_CH5_EN			(0x1 << 21)
+#define AST_ADC_CTRL_CH4_EN			(0x1 << 20)
+#define AST_ADC_CTRL_CH3_EN			(0x1 << 19)
+#define AST_ADC_CTRL_CH2_EN			(0x1 << 18)
+#define AST_ADC_CTRL_CH1_EN			(0x1 << 17)
+#define AST_ADC_CTRL_CH0_EN			(0x1 << 16)
+
+#if defined(CONFIG_ARCH_AST2300)
+#define AST_ADC_CTRL_COMPEN_CLR		(0x1 << 6)
+#define AST_ADC_CTRL_COMPEN			(0x1 << 5)
+#elif defined(CONFIG_ARCH_AST2400)
+#define AST_ADC_CTRL_COMPEN			(0x1 << 4)
+#elif defined(CONFIG_ARCH_AST2500)
+#define AST_ADC_CTRL_INIT_RDY		(0x1 << 8)
+#define AST_ADC_CTRL_COMPEN			(0x1 << 5)
+#else
+#err "ERROR define COMPEN ADC"
+#endif
+
+#if defined(CONFIG_ARCH_AST1010)
+#define AST_ADC_CTRL_OTP			(0x1 << 3)
+#define AST_ADC_CTRL_PWR_DWN		(0x1 << 2)
+#define AST_ADC_CTRL_TEST			(0x1 << 1)
+#endif
+
+#define AST_ADC_CTRL_NORMAL			(0x7 << 1)
+
+#define AST_ADC_CTRL_EN				(0x1)
+
+
+/* AST_ADC_IER : 0x04 - Interrupt Enable and Interrupt status	*/
+#define AST_ADC_IER_CH15			(0x1 << 31)
+#define AST_ADC_IER_CH14			(0x1 << 30)
+#define AST_ADC_IER_CH13			(0x1 << 29)
+#define AST_ADC_IER_CH12			(0x1 << 28)
+#define AST_ADC_IER_CH11			(0x1 << 27)
+#define AST_ADC_IER_CH10			(0x1 << 26)
+#define AST_ADC_IER_CH9				(0x1 << 25)
+#define AST_ADC_IER_CH8				(0x1 << 24)
+#define AST_ADC_IER_CH7				(0x1 << 23)
+#define AST_ADC_IER_CH6				(0x1 << 22)
+#define AST_ADC_IER_CH5				(0x1 << 21)
+#define AST_ADC_IER_CH4				(0x1 << 20)
+#define AST_ADC_IER_CH3				(0x1 << 19)
+#define AST_ADC_IER_CH2				(0x1 << 18)
+#define AST_ADC_IER_CH1				(0x1 << 17)
+#define AST_ADC_IER_CH0				(0x1 << 16)
+#define AST_ADC_STS_CH15			(0x1 << 15)
+#define AST_ADC_STS_CH14			(0x1 << 14)
+#define AST_ADC_STS_CH13			(0x1 << 13)
+#define AST_ADC_STS_CH12			(0x1 << 12)
+#define AST_ADC_STS_CH11			(0x1 << 11)
+#define AST_ADC_STS_CH10			(0x1 << 10)
+#define AST_ADC_STS_CH9				(0x1 << 9)
+#define AST_ADC_STS_CH8				(0x1 << 8)
+#define AST_ADC_STS_CH7				(0x1 << 7)
+#define AST_ADC_STS_CH6				(0x1 << 6)
+#define AST_ADC_STS_CH5				(0x1 << 5)
+#define AST_ADC_STS_CH4				(0x1 << 4)
+#define AST_ADC_STS_CH3				(0x1 << 3)
+#define AST_ADC_STS_CH2				(0x1 << 2)
+#define AST_ADC_STS_CH1				(0x1 << 1)
+#define AST_ADC_STS_CH0				(0x1)
+
+/* AST_ADC_VGA	: 0x08 - VGA Detect Control */
+#define AST_ADC_VGA_EN				(0x1 << 16)
+#define AST_ADC_VGA_DIV_MASK		(0x3ff)
+
+/* AST_ADC_CLK : 0x0c - ADC CLK Control */
+#define AST_ADC_CLK_PRE_DIV_MASK	(0x7fff << 17)
+#define AST_ADC_CLK_PRE_DIV			(0x1 << 17)
+#define AST_ADC_CLK_INVERT			(0x1 << 16)		//only for ast2300
+#define AST_ADC_CLK_DIV_MASK		(0x3ff)
+
+#define AST_ADC_H_CH_MASK			(0x3ff << 16)
+#define AST_ADC_L_CH_MASK			(0x3ff)
+
+#define AST_ADC_H_BOUND				(0x3ff << 16)
+#define AST_ADC_L_BOUND				(0x3ff)
+
+#define AST_ADC_HYSTER_EN			(0x1 << 31)
+
+#if defined(CONFIG_ARCH_AST2500)
+/* AST_ADC_CH16	 : 0xD0 - */
+/* AST_ADC_CH17	 : 0xD4 - */
+#define AST_TEMP_CH_RDY				(0x1 << 31)
+#define AST_GET_TEMP_A_MASK(x)		((x >>16) & 0xfff)
+#define AST_TEMP_CH_EN				(0x1 << 15)		
+#define AST_GET_TEMP_B_MASK(x)		(x & 0xfff)
+	
+
+#endif
+
+#endif /* __ASM_ARCH_REGS_ADC_H */
diff --git a/arch/arm/plat-aspeed/include/plat/regs-ast1070-intc.h b/arch/arm/plat-aspeed/include/plat/regs-ast1070-intc.h
new file mode 100644
index 0000000..00dd1cb
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-ast1070-intc.h
@@ -0,0 +1,42 @@
+/* arch/arm/mach-aspeed/include/mach/regs-intr.h
+ *
+ * Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *   History      : 
+ *    1. 2012/08/15 Ryan Chen Create
+ * 
+********************************************************************************/
+#ifndef __ASPEED_AST1070_INTR_H
+#define __ASPEED_AST1070_INTR_H                     1
+
+#include <asm/io.h>
+#include <mach/platform.h>
+#include <mach/irqs.h>
+
+/*
+ * VIC Register (VA)
+ */
+
+#define VIC_BASE_VA(x)             		IO_ADDRESS2(AST_C0_VIC_BASE + (0x10000*x)) 
+
+#define AST_IRQ_STS(x)					(VIC_BASE_VA(x) + 0x00)
+#define AST_RAW_STS(x)					(VIC_BASE_VA(x) + 0x08)
+#define AST_INTR_EN(x)					(VIC_BASE_VA(x) + 0x10)
+#define AST_INTR_DIS(x)					(VIC_BASE_VA(x) + 0x14)
+#define AST_INTR_SENSE(x)				(VIC_BASE_VA(x) + 0x24)
+#define AST_INTR_BOTH_EDGE(x)			(VIC_BASE_VA(x) + 0x28)
+#define AST_INTR_EVENT(x)				(VIC_BASE_VA(x) + 0x2C)
+
+#define IRQ_SET_LEVEL_TRIGGER(x,irq_no)   *((volatile unsigned long*)AST_INTR_SENSE(x)) |= 1 << (irq_no)
+#define IRQ_SET_EDGE_TRIGGER(x,irq_no)    *((volatile unsigned long*)AST_INTR_SENSE(x)) &= ~(1 << (irq_no))
+#define IRQ_SET_RISING_EDGE(x,irq_no)     *((volatile unsigned long*)AST_INTR_EVENT(x)) |= 1 << (irq_no)
+#define IRQ_SET_FALLING_EDGE(x,irq_no)    *((volatile unsigned long*)AST_INTR_EVENT(x)) &= ~(1 << (irq_no))
+#define IRQ_SET_HIGH_LEVEL(x,irq_no)      *((volatile unsigned long*)AST_INTR_EVENT(x)) |= 1 << (irq_no)
+#define IRQ_SET_LOW_LEVEL(x,irq_no)       *((volatile unsigned long*)AST_INTR_EVENT(x)) &= ~(1 << (irq_no))
+
+
+#endif
diff --git a/arch/arm/plat-aspeed/include/plat/regs-ast1070-lpc.h b/arch/arm/plat-aspeed/include/plat/regs-ast1070-lpc.h
new file mode 100644
index 0000000..22f8475
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-ast1070-lpc.h
@@ -0,0 +1,117 @@
+/* arch/arm/plat-aspeed/include/mach/regs-lpc.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED LPC Controller
+*/
+
+#ifndef __AST1070_LPC_H_
+#define __AST1070_LPC_H_
+
+#define AST_LPC_HICR0				0x000
+#define	AST_LPC_HICR1				0x004
+#define AST_LPC_HICR2				0x008
+#define AST_LPC_HICR3				0x00C
+#define AST_LPC_HICR4				0x010
+#define AST_LPC_LADR3H				0x014
+#define AST_LPC_LADR3L				0x018
+#define AST_LPC_LADR12H				0x01C
+#define AST_LPC_LADR12L				0x020
+#define AST_LPC_IDR1				0x024
+#define AST_LPC_IDR2				0x028
+#define AST_LPC_IDR3				0x02C
+#define AST_LPC_ODR1				0x030
+#define AST_LPC_ODR2				0x034
+#define AST_LPC_ODR3				0x038
+#define AST_LPC_STR1				0x03C
+#define AST_LPC_STR2				0x040
+#define AST_LPC_STR3				0x044
+////
+#define AST_LPC_SIRQCR0				0x048
+#define AST_LPC_SIRQCR1				0x04C
+#define AST_LPC_SIRQCR2				0x050
+#define AST_LPC_SIRQCR3				0x06C
+////
+#define AST_LPC_ADR1				0x070
+#define AST_LPC_IRQ1				0x074
+#define AST_LPC_ADR2				0x078
+#define AST_LPC_IRQ2				0x07C
+#define AST_LPC_ADR3				0x080
+#define AST_LPC_IRQ3				0x084
+
+#define AST_LPC_DEV_ADDRM0			0x100
+#define AST_LPC_DEV_ADDRM1			0x104
+#define AST_LPC_DEV_ADDRM2			0x108
+#define AST_LPC_DEV_ADDRM3			0x10C
+#define AST_LPC_DEV_ADDR0			0x110
+#define AST_LPC_DEV_ADDR1			0x114
+#define AST_LPC_DEV_ADDR2			0x118
+#define AST_LPC_DEV_ADDR3			0x11C
+#define AST_LPC_DEC_ADDR0			0x120
+#define AST_LPC_DEC_ADDR1			0x124
+#define AST_LPC_DEC_RANGE0			0x128
+#define AST_LPC_DEC_RANGE1			0x12C
+
+#define AST_LPC_MBXDAT0				0x180
+#define AST_LPC_MBXDAT1				0x184
+#define AST_LPC_MBXDAT2				0x188
+#define AST_LPC_MBXDAT3				0x18C
+#define AST_LPC_MBXDAT4				0x190
+#define AST_LPC_MBXDAT5				0x194
+#define AST_LPC_MBXDAT6				0x198
+#define AST_LPC_MBXDAT7				0x19C
+#define AST_LPC_MBXDAT8				0x1A0
+#define AST_LPC_MBXDAT9				0x1A4
+#define AST_LPC_MBXDATA				0x1A8
+#define AST_LPC_MBXDATB				0x1AC
+#define AST_LPC_MBXDATC				0x1B0
+#define AST_LPC_MBXDATD				0x1B4
+#define AST_LPC_MBXDATE				0x1B8
+#define AST_LPC_MBXDATF				0x1BC
+
+#define AST_LPC_MBXSTS0				0x1C0
+#define AST_LPC_MBXSTS1				0x1C4
+
+#define AST_LPC_MBXBICR				0x1C8
+#define AST_LPC_MBXHICR				0x1CC
+#define AST_LPC_MBXBIE0				0x1D0
+#define AST_LPC_MBXBIE1				0x1D4
+#define AST_LPC_MBXHIE0				0x1D8
+#define AST_LPC_MBXHIE1				0x1DC
+
+#define AST_LPC_PIN_MON				0x200
+#define AST_LPC_SIRQ_CTRL			0x208
+#define AST_LPC_INT_STS				0x20C
+#define AST_LPC_CTRL_STS			0x210
+#define AST_LPC_PME					0x218
+#define AST_LPC_SMI					0x21C
+#define AST_LPC_80H_ADDR0			0x220
+#define AST_LPC_80H_ADDR1			0x224
+#define AST_LPC_80H_DATA			0x228
+#define AST_LPC_80H_CTRL			0x22C
+
+#define AST_LPC_CHIP_VER			0x240
+#define AST_LPC_CHIP_REVER			0x244
+#define AST_LPC_BMC_SCH0			0x248
+#define AST_LPC_BMC_SCH1			0x24C
+#define AST_LPC_NODE_SCH0			0x250
+#define AST_LPC_NODE_SCH1			0x254
+#define AST_LPC_NODE_SCH2			0x258
+#define AST_LPC_NODE_SCH3			0x25C
+
+
+
+
+
+
+
+
+
+
+
+#endif 
diff --git a/arch/arm/plat-aspeed/include/plat/regs-ast1070-scu.h b/arch/arm/plat-aspeed/include/plat/regs-ast1070-scu.h
new file mode 100644
index 0000000..a5a4f95
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-ast1070-scu.h
@@ -0,0 +1,95 @@
+/* arch/arm/mach-aspeed/include/mach/regs-ast1070-scu.h
+ *
+ * Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *   History      : 
+ *    1. 2013/05/15 Ryan Chen Create
+ * 
+********************************************************************************/
+#ifndef __AST1070_SCU_H
+#define __AST1070_SCU_H                     1
+
+/*
+ *  Register for SCU
+ *  */
+#define AST1070_SCU_PROTECT			0x00		/*	protection key register	*/
+#define AST1070_SCU_RESET			0x04		/*	system reset control register */
+#define AST1070_SCU_MISC_CTRL		0x08		/*	misc control register	*/
+#define AST1070_SCU_UART_MUX		0x0C		/*	UART Mux control register	*/
+#define AST1070_SCU_SPI_USB_MUX		0x10		/*	SPI/USB Mux control register	*/
+#define AST1070_SCU_IO_DRIVING		0x14		/*	I/O Driving Strength control register	*/
+#define AST1070_SCU_IO_PULL			0x18		/*	I/O Internal Pull control register	*/
+#define AST1070_SCU_IO_SLEW			0x1C		/*	I/O Slew Rate control register	*/
+#define AST1070_SCU_IO_SCHMITT		0x20		/*	I/O Schmitt Trigger Control register	*/
+#define AST1070_SCU_IO_SELECT		0x24		/*	I/O Port Selection register	*/
+#define AST1070_SCU_TRAP			0x30		/*	HW TRAPPING register	*/
+#define AST1070_SCU_CHIP_ID			0x34		/*	CHIP ID register	*/
+
+
+/*	AST1070_SCU_PROTECT: 0x00  - protection key register */
+#define AST1070_SCU_PROTECT_UNLOCK			0x16881A78
+
+/*	AST1070_SCU_RESET :0x04	 - system reset control register */
+#define SCU_RESET_DMA				(0x1 << 11)
+#define SCU_RESET_SPI_M				(0x1 << 10)
+#define SCU_RESET_SPI_S				(0x1 << 9)
+#define SCU_RESET_N4_LPC			(0x1 << 8)
+#define SCU_RESET_N3_LPC			(0x1 << 7)
+#define SCU_RESET_N2_LPC			(0x1 << 6)
+#define SCU_RESET_N1_LPC			(0x1 << 5)
+#define SCU_RESET_I2C				(0x1 << 4)
+#define SCU_RESET_N4_UART			(0x1 << 3)
+#define SCU_RESET_N3_UART			(0x1 << 2)
+#define SCU_RESET_N2_UART			(0x1 << 1)
+#define SCU_RESET_N1_UART			(0x1 << 0)
+
+/*	AST1070_SCU_MISC_CTRL		0x08		misc control register	*/
+#define SCU_DMA_M_S_MASK			(0x3 << 9)
+
+#define SCU_DMA_SLAVE_EN			(0x1 << 10)
+#define SCU_DMA_MASTER_EN			(0x1 << 9)
+
+/*	AST1070_SCU_UART_MUX		0x0C	UART Mux control register	*/
+#define UART_MUX_MASK(x)			(0xff << (x*8))
+
+#define BMC_UART_CTRL(x)			(6 + (x*8))
+#define BMC_UART_CTRL_MASK(x)		(0x3 << (6 + (x*8)))
+#define SET_BMC_UART_CTRL(x,v)		((v) << (6 + (x*8)))
+#define BMC_UART_FROM_N1			0
+#define BMC_UART_FROM_PAD1			1
+#define BMC_UART_FROM_NONE			2
+
+#define NODE_UART_CTRL(x)			(3 + (x*8))
+#define NODE_UART_CTRL_MASK(x)		(0x7 << (3 + (x*8)))
+#define SET_NODE_UART_CTRL(x,v)		((v) << (3 + (x*8)))
+#define NODE_UART_FROM_BMC			0
+#define NODE_UART_FROM_PAD1			1
+#define NODE_UART_FROM_PAD2			2
+#define NODE_UART_FROM_PAD3			3
+#define NODE_UART_FROM_PAD4			4
+#define NODE_UART_FROM_NONE			5
+#define NODE_UART_FROM_N2			6
+#define NODE_UART_FROM_N3			7
+
+
+#define SCU_UART_IO_PAD(x)			(x*8)
+#define UART_IO_PAD_MASK(x)			(0x7 << (x*8))
+#define SET_UART_IO_PAD(x,v)		((v) << (x*8))
+#define PAD_FROM_NONE				0
+#define PAD_FROM_N1_UART			1
+#define PAD_FROM_N2_UART			2
+#define PAD_FROM_N3_UART			3
+#define PAD_FROM_N4_UART			4
+#define PAD_FROM_BMC				5
+
+/*	AST1070_SCU_TRAP			0x30		HW TRAPPING register	*/
+#define TRAP_DEVICE_SLAVE			(0x1 << 2)
+#define TRAP_MULTI_MASTER			(0x1 << 1)
+#define TRAP_LPC_PLUS_MODE			(0x1 << 0)
+
+#endif
+
diff --git a/arch/arm/plat-aspeed/include/plat/regs-crt.h b/arch/arm/plat-aspeed/include/plat/regs-crt.h
new file mode 100644
index 0000000..6749285
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-crt.h
@@ -0,0 +1,183 @@
+/* linux/include/asm-arm/arch-aspeed/regs-crt.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef ___ASM_ARCH_REGS_CRT_H
+#define ___ASM_ARCH_REGS_CRT_H 
+
+/* CRT control registers */
+
+
+//////////////////////////////////////////////////////////////////
+#define AST3000_VGA1_CTLREG	0x00
+#define AST3000_VGA1_CTLREG2	0x04
+#define AST3000_VGA1_STATUSREG	0x08 
+#define AST3000_VGA1_PLL	0x0C
+#define AST3000_VGA1_HTREG	0x10
+#define AST3000_VGA1_HRREG	0x14
+#define AST3000_VGA1_VTREG	0x18
+#define AST3000_VGA1_VRREG	0x1C
+#define AST3000_VGA1_STARTADDR	0x20
+#define AST3000_VGA1_OFFSETREG	0x24
+#define AST3000_VGA1_THRESHOLD	0x28
+
+#define AST3000_VGA2_CTLREG	0x60
+#define AST3000_VGA2_CTLREG2	0x64
+#define AST3000_VGA2_STATUSREG	0x68 
+#define AST3000_VGA2_PLL	0x6C
+#define AST3000_VGA2_HTREG	0x70
+#define AST3000_VGA2_HRREG	0x74
+#define AST3000_VGA2_VTREG	0x78
+#define AST3000_VGA2_VRREG	0x7C
+#define AST3000_VGA2_STARTADDR	0x80
+#define AST3000_VGA2_OFFSETREG	0x84
+#define AST3000_VGA2_THRESHOLD	0x88
+//////////////////////////////////////////////////////////////////
+
+//0x00 ~ 0x5F Reserved - FB0 
+//0x60 ~ 90 FB1
+#define AST_CRT_CTRL1				0x60
+#define AST_CRT_CTRL2				0x64
+#define AST_CRT_STS					0x68
+#define AST_CRT_PLL					0x6C
+#define AST_CRT_HORIZ0				0x70
+#define AST_CRT_HORIZ1				0x74
+#define AST_CRT_VERTI0				0x78
+#define AST_CRT_VERTI1				0x7C
+#define AST_CRT_ADDR				0x80
+#define AST_CRT_OFFSET				0x84
+#define AST_CRT_THROD				0x88
+#define AST_CRT_XSCALING			0x8C
+//0x8c Reserved
+//0x90 ~ Cursor
+#define AST_CRT_CURSOR0				0x90
+#define AST_CRT_CURSOR1				0x94
+#define AST_CRT_CURSOR2				0x98
+#define AST_CRT_UADDR				0x9C
+//0x9c Reserved
+//0xA0 ~ OSD
+#define AST_CRT_OSDH				0xA0
+#define AST_CRT_OSDV				0xA4
+#define AST_CRT_OSDADDR				0xA8
+#define AST_CRT_OSDDISP				0xAC
+#define AST_CRT_OSDTHROD			0xB0
+#define AST_CRT_VADDR				0xB4
+
+//0xb4 Reserved
+#define AST_CRT_STS_V				0xB8
+#define AST_CRT_SCRATCH				0xBC
+#define AST_CRT_X					0xC0
+//0xC4
+#define AST_CRT_OSD_COLOR			0xE0
+
+/* AST_CRT_CTRL1 - 0x60 : CRT Control Register I */
+#define CRT_CTRL_VERTICAL_INTR_STS	(0x1 << 31) 
+#define CRT_CTRL_VERTICAL_INTR_EN	(0x1 << 30) 
+//24~28 reserved
+#define CRT_CTRL_DESK_OFF			(0x1 << 23) 
+#define CRT_CTRL_FSYNC_OFF			(0x1 << 22) 
+#define CRT_CTRL_FSYNC_POLARITY		(0x1 << 21) 
+#define CRT_CTRL_SCREEN_OFF			(0x1 << 20) 
+#define CRT_CTRL_VSYNC_OFF			(0x1 << 19) 
+#define CRT_CTRL_HSYNC_OFF			(0x1 << 18) 
+#define CRT_CTRL_VSYNC_POLARITY		(0x1 << 17) 
+#define CRT_CTRL_HSYNC_POLARITY		(0x1 << 16) 
+#define CRT_CTRL_TILE_EN			(0x1 << 15) 
+#define CRT_CTRL_HDTVYUV_EN			(0x1 << 14) 
+#define CRT_CTRL_YUV_FORMAT(x)		(x << 12) 
+#define YUV_MODE0					0
+#define YUV_MODE1					1
+#define YUV_MODE2					2
+// bit 11 reserved 
+#define CRT_CTRL_HW_CURSOR_FORMAT	(0x1 << 10) // 0: XRGB4444, 1:ARGB4444
+#define CRT_CTRL_FORMAT_MASK		(0x7 << 7)
+#define CRT_CTRL_FORMAT(x)			(x << 7)
+#define COLOR_RGB565				(0)
+#define COLOR_YUV444				(1)
+#define COLOR_XRGB8888				(2)
+#define COLOR_YUV444_2RGB			(5)
+#define CRT_CTRL_ENVEFLIP			(0x1 << 6)
+//bit 5
+#define CRT_CTRL_SCALING_X			(0x1 << 4)
+#define CRT_CTRL_INTER_TIMING		(0x1 << 3)
+#define CRT_CTRL_OSD_EN				(0x1 << 2)
+#define CRT_CTRL_HW_CURSOR_EN		(0x1 << 1)
+#define CRT_CTRL_GRAPHIC_EN			(0x1)
+
+/*AST_CRT_CTRL2 - 0x64 : CRT Control Register II */
+#define CRT_CTRL_VLINE_NUM_MASK		(0xfff << 20)
+#define CRT_CTRL_VLINE_NUM(x)		(x << 20)
+#define CRT_CTRL_TESTDVO_MASK		(0xfff << 8)
+#define CRT_CTRL_TESTDVO(x)			(x << 8)
+#define CRT_CTRL_DVO_EN				(0x1 << 7)
+#define CRT_CTRL_DVO_DUAL			(0x1 << 6)
+#define CRT_CTRL_FIFO_FULL			(0x1 << 5)
+#define CRT_CTRL_TEST_EN			(0x1 << 4)
+#define CRT_CTRL_SIGN_DON			(0x1 << 3)
+#define CRT_CTRL_SIGN_TRIGGER		(0x1 << 2)
+#define CRT_CTRL_DAC_TEST_EN		(0x1 << 1)
+#define CRT_CTRL_DAC_PWR_EN			(0x1)
+
+/* AST_CRT_STS	- 0x68 : CRT Status Register */
+#define CRT_STS_RED_RB(x)			(x << 24)
+#define CRT_STS_GREEN_RB(x)			(x << 16)
+#define CRT_STS_BLUE_RB(x)			(x << 8)
+#define CRT_STS_DAC_SENSE_EN		(0x1 << 7)
+//6 reserved
+#define CRT_STS_ODDFIELD_SYNC		(0x1 << 5)
+#define CRT_STS_ODDFIELD			(0x1 << 4)
+#define CRT_STS_HDISPLAY_RB			(0x1 << 3)
+#define CRT_STS_HRETRACE_RB			(0x1 << 2)
+#define CRT_STS_VDISPLAY_RB			(0x1 << 1)
+#define CRT_STS_VRETRACE_RB			(0x1)
+
+/* AST_CRT_PLL -  0x6C : CRT Video PLL Setting Register */
+#define CRT_PLL_DAC_MODE_SENSE(x)	(x << 30)
+#define CRT_PLL_DAC_SENSE(x)		(x << 28)
+#define CRT_PLL_BYPASS				(0x1 << 17)
+#define CRT_PLL_PWR_DWN				(0x1 << 16)
+#define CRT_PLL_POST_DIVIDER(x)		(((x & 0x3) << 13) | (((x >> 2) & 0xf) << 18) | (((x >> 6) & 0x1) << 23) | (((x >> 7) & 0x1) << 22))
+#define CRT_PLL_DENUM(x)			(x << 8)
+#define CRT_PLL_NUM(x)				(x)
+
+/* AST_CRT_HORIZ0 - 0x70 : CRT Horizontal Total & Display Enable End Register */
+#define CRT_H_TOTAL(x)				(x)
+#define CRT_H_DE(x) 				(x << 16)
+
+/* AST_	0x74 : CRT Horizontal Retrace Start & End Register */
+#define CRT_H_RS_START(x)			(x)
+#define CRT_H_RS_END(x)				(x << 16)
+
+/* AST_CRT_ - 0x78 : CRT Horizontal Total & Display Enable End Register */
+#define CRT_V_TOTAL(x)				(x)
+#define CRT_V_DE(x) 				(x << 16)
+
+/* AST_	0x7C : CRT Horizontal Retrace Start & End Register */
+#define CRT_V_RS_START(x)			(x)
+#define CRT_V_RS_END(x)				(x << 16)
+
+/* AST_CRT_OFFSET - 0x84 : CRT Display Offset & Terminal Count Register */
+#define CRT_DISP_OFFSET(x)			(x)
+#define CRT_TERM_COUNT(x)			(x << 16)
+
+/* AST_CRT_THROD - 0x88 : CRT Threadhold Register */
+#define CRT_THROD_LOW(x)			(x)
+#define CRT_THROD_HIGH(x)			(x << 8)
+#define CRT_THROD_X_SCALING(x)		(x << 16)
+#define CRT_THROD_CRT2Y				(0x1 << 20)
+
+/* AST_CRT_XSCALING - 0x8C : CRT X Scaling-up Factor Register */
+
+
+/* AST_CRT_CURSOR0	: 0x90 - CRT Hardware Cursor X & Y Offset Register */
+#define CRT_HW_CURSOR_X_OFFSET(x)			(x)
+#define CRT_HW_CURSOR_Y_OFFSET(x)			(x << 16)
+
+/* AST_CRT_CURSOR1 : 0x94 - CRT Hardware Cursor X & Y Position Register */
+#define CRT_HW_CURSOR_X_POSITION(x)			(x)
+#define CRT_HW_CURSOR_Y_POSITION(x)			(x << 16)
+
+#endif /* ___ASM_ARCH_REGS_CRT_H */
diff --git a/arch/arm/plat-aspeed/include/plat/regs-fmc.h b/arch/arm/plat-aspeed/include/plat/regs-fmc.h
new file mode 100644
index 0000000..25c3046
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-fmc.h
@@ -0,0 +1,112 @@
+/* arch/arm/plat-aspeed/include/mach/regs-smc.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED Static memory ctrol 
+*/
+
+#ifndef __ASM_ARCH_REGS_FMC_H
+#define __ASM_ARCH_REGS_FMC_H __FILE__
+
+#define FMC_CE_TYPE				0x00
+#define FMC_CE_CTRL				0x04
+#define FMC_INTR_CTRL			0x08
+#define FMC_CE0_CTRL			0x10
+#define FMC_CE1_CTRL			0x14
+#define FMC_CE2_CTRL			0x18
+#define FMC_CE3_CTRL			0x1c
+#define FMC_CE4_CTRL			0x20
+
+#define FMC_CE0_ADDR			0x30
+#define FMC_CE1_ADDR			0x34
+#define FMC_CE2_ADDR			0x38
+#define FMC_CE3_ADDR			0x3c
+#define FMC_CE4_ADDR			0x40
+
+#define FMC_MISC_CTRL1			0x50
+#define FMC_MISC_CTRL2			0x54
+#define FMC_NAND_CTRL			0x58
+#define FMC_NAND_ECC			0x5c
+#define FMC_NAND_ECC_CK1		0x60
+#define FMC_NAND_ECC_CK2		0x64
+#define FMC_NAND_ECC_CK3		0x68
+#define FMC_NAND_ECC_GEN1		0x6c
+#define FMC_NAND_ECC_GEN2		0x70
+#define FMC_NAND_ECC_GEN3		0x74
+#define FMC_NAND_ECC_CK_R1		0x78
+#define FMC_NAND_ECC_CK_R2		0x7c
+#define FMC_DMA_CTRL			0x80
+#define FMC_DMA_FLASH_ADDR		0x84
+#define FMC_DMA_DRAM_ADDR		0x88
+#define FMC_DMA_LEN				0x8C
+#define FMC_CHECK_SUM			0x90
+#define FMC_SPI_TIMING			0x94
+
+/* FMC_CE_TYPE				0x00 */
+#define FMC_SET_WRITE_CS(x)		(0x1 << (x+16))
+#define FMC_MASK_TYPE_CS(x)		(~(0x3 << (2*x)))
+#define FMC_SET_TYPE_NAND_CS(x)	(0x1 << (2*x))
+#define FMC_SET_TYPE_SPI_CS(x)	(0x2 << (2*x))	
+
+#define FMC_TYPE_NOR 			0
+#define FMC_TYPE_NAND 			1
+#define FMC_TYPE_SPI 			2
+
+
+/* FMC_CE0_CTRL	for NAND 0x10, 0x14, 0x18, 0x1c, 0x20 */
+#define NAND_T_WEH(x)			(x << 28)
+#define NAND_T_WEL(x)			(x << 24)
+#define NAND_T_REH(x)			(x << 20)
+#define NAND_T_REL(x)			(x << 16)
+#define NAND_T_CESH(x)			(x << 12)
+#define NAND_T_WTR(x)			(x << 10)
+#define NAND_T_R(x)				(x << 4)
+#define NAND_ADDR_CYCLE			(1 << 3)
+#define NAND_CE_ACTIVE			(1 << 2)
+#define NAND_OP_MODE				(1 << 0)
+
+/* FMC_CE0_CTRL	for SPI 0x10, 0x14, 0x18, 0x1c, 0x20 */
+#define SPI_IO_MODE(x)			(x << 28)
+#define SPI_CE_WIDTH(x)			(x << 24)
+#define SPI_CMD_DATA(x)			(x << 16)
+#define SPI_DUMMY_CMD			(1 << 15)
+#define SPI_DUMMY_HIGH			(1 << 14)
+#define SPI_CLK_DIV				(1 << 13)
+#define SPI_ADDR_CYCLE			(1 << 13)
+#define SPI_CMD_MERGE_DIS		(1 << 12)
+#define SPI_T_CLK				(x << 8)
+#define SPI_DUMMY_LOW			(x << 6)
+#define SPI_LSB_FIRST_CTRL		(1 << 5)
+#define SPI_CPOL_1				(1 << 4)
+#define SPI_DUAL_DATA			(1 << 3)
+#define SPI_CE_INACTIVE			(1 << 2)
+#define SPI_CMD_MODE			(x)
+#define SPI_CMD_NOR_R_MODE		0
+#define SPI_CMD_FAST_R_MODE		1
+#define SPI_CMD_NOR_W_MODE		2
+#define SPI_CMD_USER_MODE		3
+
+
+/* FMC_CE0_ADDR			0x30 0x34 0x38 0x3c 0x40*/
+#define FMC_END_ADDR(x)			(x << 24)
+#define FMC_START_ADDR(x)		(x << 16)
+
+
+/* FMC_MISC_CTRL1			0x50 */
+#define READ_BUSY_PIN_STS		(1 << 3)
+
+/* FMC_NAND_ECC			0x5c */
+#define NAND_ECC_RESET			(1 << 3)
+#define NAND_ECC_ENABLE			(1 << 2)
+#define NAND_ECC_DATA_BLK_512	2
+#define NAND_ECC_DATA_BLK_256	1
+#define NAND_ECC_DATA_BLK_128	0
+
+
+
+#endif /* __ASM_ARCH_REGS_FMC_H */
diff --git a/arch/arm/plat-aspeed/include/plat/regs-gpio.h b/arch/arm/plat-aspeed/include/plat/regs-gpio.h
new file mode 100644
index 0000000..d6e7de0
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-gpio.h
@@ -0,0 +1,338 @@
+/* arch/arm/plat-aspeed/include/mach/regs-gpio.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED I2C Controller
+*/
+
+#ifndef __ASM_ARCH_REGS_GPIO_H
+#define __ASM_ARCH_REGS_GPIO_H __FILE__
+
+/*AST GPIO Register Definition */
+#define AST_GPIO_DATA						0x000
+#define AST_GPIO_DIR						0x004
+#define AST_GPIO_INT_EN						0x008
+#define AST_GPIO_INT_SEN_T0					0x00c
+#define AST_GPIO_INT_SEN_T1					0x010
+#define AST_GPIO_INT_SEN_T2					0x014
+#define AST_GPIO_INT_STS					0x018
+#define AST_GPIO_RST_TOR					0x01c
+#define AST_EXT_GPIO_DATA					0x020
+#define AST_EXT_GPIO_DIR					0x024
+#define AST_EXT_GPIO_INT_EN					0x028
+#define AST_EXT_GPIO_INT_SEN_T0				0x02c
+#define AST_EXT_GPIO_INT_SEN_T1				0x030
+#define AST_EXT_GPIO_INT_SEN_T2				0x034
+#define AST_EXT_GPIO_INT_STS				0x038
+#define AST_EXT_GPIO_RST_TOR				0x03c
+#define AST_GPIO_DEBOUNCE_SET1				0x040			//A/B/C/D
+#define AST_GPIO_DEBOUNCE_SET2				0x044			//A/B/C/D
+#define AST_EXT_GPIO_DEBOUNCE_SET1			0x048			//E/F/G/H
+#define AST_EXT_GPIO_DEBOUNCE_SET2			0x04C			//E/F/G/H
+#define AST_DEBOUNCE_TIME_SET1				0x050
+#define AST_DEBOUNCE_TIME_SET2				0x054
+#define AST_DEBOUNCE_TIME_SET3				0x058
+#define AST_GPIO_CMD_S0						0x060
+#define AST_GPIO_CMD_S1						0x064
+#define AST_EXT_GPIO_CMD_S0					0x068
+#define AST_EXT_GPIO_CMD_S1					0x06C
+#define AST_SIMPLE_GPIO_DATA0				0x070
+#define AST_SIMPLE_GPIO_DIR0				0x074
+#define AST_SIMPLE_GPIO_DATA1				0x078
+#define AST_SIMPLE_GPIO_DIR1				0x07C
+#define AST_SIMPLE_GPIO_DATA2				0x080
+#define AST_SIMPLE_GPIO_DIR2				0x084
+#define AST_SIMPLE_GPIO_DATA3				0x088
+#define AST_SIMPLE_GPIO_DIR3				0x08C
+#define AST_SIMPLE_GPIO0_CMD_S0				0x090
+#define AST_SIMPLE_GPIO0_CMD_S1				0x094
+#define AST_SIMPLE_GPIO0_INT_EN				0x098
+#define AST_SIMPLE_GPIO0_INT_SEN_T0			0x09c
+#define AST_SIMPLE_GPIO0_INT_SEN_T1			0x0a0
+#define AST_SIMPLE_GPIO0_INT_SEN_T2			0x0a4
+#define AST_SIMPLE_GPIO0_INT_STS			0x0a8
+#define AST_SIMPLE_GPIO0_RST_TOR			0x0ac
+#define AST_SIMPLE_GPIO0_DEBOUNCE_SET1		0x0b0
+#define AST_SIMPLE_GPIO0_DEBOUNCE_SET2		0x0b4
+#define AST_SIMPLE_GPIO0_INT_MASK			0x0b8
+#define AST_GPIO_DATA_READ					0x0c0
+#define AST_EXT_GPIO_DATA_READ				0x0c4
+#define AST_SIMPLE_GPIO0_DATA_READ			0x0c8
+#define AST_SIMPLE_GPIO1_DATA_READ			0x0cc
+#define AST_SIMPLE_GPIO2_DATA_READ			0x0d0
+#define AST_SIMPLE_GPIO3_DATA_READ			0x0d4
+#define AST_SIMPLE_GPIO4_DATA_READ			0x0d8
+#define AST_SIMPLE_GPIO1_CMD_S0				0x0e0
+#define AST_SIMPLE_GPIO1_CMD_S1				0x0e4
+#define AST_SIMPLE_GPIO1_INT_EN				0x0e8
+#define AST_SIMPLE_GPIO1_INT_SEN_T0			0x0ec
+#define AST_SIMPLE_GPIO1_INT_SEN_T1			0x0f0
+#define AST_SIMPLE_GPIO1_INT_SEN_T2			0x0f4
+#define AST_SIMPLE_GPIO1_INT_STS			0x0f8
+#define AST_SIMPLE_GPIO1_RST_TOR			0x0fc
+#define AST_SIMPLE_GPIO1_DEBOUNCE_SET1		0x100
+#define AST_SIMPLE_GPIO1_DEBOUNCE_SET2		0x104
+#define AST_SIMPLE_GPIO1_INT_MASK			0x108
+#define AST_SIMPLE_GPIO2_CMD_S0				0x110
+#define AST_SIMPLE_GPIO2_CMD_S1				0x114
+#define AST_SIMPLE_GPIO2_INT_EN				0x118
+#define AST_SIMPLE_GPIO2_INT_SEN_T0			0x11c
+#define AST_SIMPLE_GPIO2_INT_SEN_T1			0x120
+#define AST_SIMPLE_GPIO2_INT_SEN_T2			0x124
+#define AST_SIMPLE_GPIO2_INT_STS			0x128
+#define AST_SIMPLE_GPIO2_RST_TOR			0x12c
+#define AST_SIMPLE_GPIO2_DEBOUNCE_SET1		0x130
+#define AST_SIMPLE_GPIO2_DEBOUNCE_SET2		0x134
+#define AST_SIMPLE_GPIO2_INT_MASK			0x138
+#define AST_SIMPLE_GPIO3_CMD_S0				0x140
+#define AST_SIMPLE_GPIO3_CMD_S1				0x144
+#define AST_SIMPLE_GPIO3_INT_EN				0x148
+#define AST_SIMPLE_GPIO3_INT_SEN_T0			0x14c
+#define AST_SIMPLE_GPIO3_INT_SEN_T1			0x150
+#define AST_SIMPLE_GPIO3_INT_SEN_T2			0x154
+#define AST_SIMPLE_GPIO3_INT_STS			0x158
+#define AST_SIMPLE_GPIO3_RST_TOR			0x15c
+#define AST_SIMPLE_GPIO3_DEBOUNCE_SET1		0x160
+#define AST_SIMPLE_GPIO3_DEBOUNCE_SET2		0x164
+#define AST_SIMPLE_GPIO3_INT_MASK			0x168
+#define AST_SIMPLE_GPIO4_CMD_S0				0x170
+#define AST_SIMPLE_GPIO4_CMD_S1				0x174
+#define AST_SIMPLE_GPIO4_INT_EN				0x178
+#define AST_SIMPLE_GPIO4_INT_SEN_T0			0x17c
+#define AST_SIMPLE_GPIO4_INT_SEN_T1			0x180
+#define AST_SIMPLE_GPIO4_INT_SEN_T2			0x184
+#define AST_SIMPLE_GPIO4_INT_STS			0x188
+#define AST_SIMPLE_GPIO4_RST_TOR			0x18c
+#define AST_SIMPLE_GPIO4_DEBOUNCE_SET1		0x190
+#define AST_SIMPLE_GPIO4_DEBOUNCE_SET2		0x194
+#define AST_SIMPLE_GPIO4_INT_MASK			0x198
+#define AST_GPIO_INT_MASK					0x1d0
+#define AST_EXT_GPIO_INT_MASK				0x1d4
+#ifdef CONFIG_ARCH_AST1010
+#else
+#define AST_SIMPLE_GPIO_DATA4				0x1e0
+#define AST_SIMPLE_GPIO_DIR4				0x1e4
+#endif
+
+//Serial GPIO
+#define AST_SGPIO_DATA						0x200
+#define AST_SGPIO_INT_EN					0x204
+#define AST_SGPIO_INT_SEN_T0				0x208
+#define AST_SGPIO_INT_SEN_T1				0x20c
+#define AST_SGPIO_INT_SEN_T2				0x210
+#define AST_SGPIO_INT_STS					0x214
+#define AST_SGPIO_RST_TOR					0x218
+#define AST_EXT_SGPIO_DATA					0x21c
+#define AST_EXT_SGPIO_INT_EN				0x220
+#define AST_EXT_SGPIO_INT_SEN_T0			0x224
+#define AST_EXT_SGPIO_INT_SEN_T1			0x228
+#define AST_EXT_SGPIO_INT_SEN_T2			0x22c
+#define AST_EXT_SGPIO_INT_STS				0x230
+#define AST_EXT_SGPIO_RST_TOR				0x234
+#define AST_SGPIO_CTRL						0x254
+#define AST_SGPIO_DATA_READ					0x270
+#define AST_EXT_SGPIO_DAT					0x274
+
+//Serial GPIO Slave Monitor
+#define AST_SGPIO_SLAVE_DATA_INIT			0x300
+#define AST_SGPIO_SLAVE_DATA_TARGET			0x304
+#define AST_SGPIO_SLAVE_DATA_LOAD			0x308
+#define AST_SGPIO_SLAVE_INT_EN0				0x30c
+#define AST_SGPIO_SLAVE_INT_EN1				0x310
+#define AST_SGPIO_SLAVE_INT_EN2				0x314
+#define AST_SGPIO_SLAVE_INT_STS0			0x318
+#define AST_SGPIO_SLAVE_INT_STS1			0x31c
+#define AST_SGPIO_SLAVE_INT_STS2			0x320
+
+/**********************************************************************************/
+/* AST_GPIO_DATA - 0x000 : A/B/C/D Data Vale  */
+#define GET_GPIOD_DATA(x)			((x&0xff000000) >> 24)
+#define SET_GPIOD_DATA(x)			(x << 24)
+#define GET_GPIOD_PIN_DATA(x,pin)	((x >> (pin + 24)) & 1)
+#define SET_GPIOD_PIN_DATA(pin)		(1<<(pin + 24))
+#define GET_GPIOC_DATA(x)			((x&0xff0000) >> 16)
+#define SET_GPIOC_DATA(x)			(x << 16)
+#define GET_GPIOC_PIN_DATA(x,pin)	((x >> (pin + 16)) & 1)
+#define SET_GPIOC_PIN_DATA(pin)		(1<<(pin + 16))
+#define GET_GPIOB_DATA(x)			((x&0xff00) >> 8)
+#define SET_GPIOB_DATA(x)			(x << 8)
+#define GET_GPIOB_PIN_DATA(x,pin)	((x >> (pin + 8)) & 1)
+#define SET_GPIOB_PIN_DATA(pin)		(1<<(pin + 8))
+#define GET_GPIOA_DATA(x)			(x&0xff)
+#define SET_GPIOA_DATA(x)			(x)
+#define GET_GPIOA_PIN_DATA(x,pin)	((x >> pin) & 1)
+#define SET_GPIOA_PIN_DATA(pin)		(1<<pin)
+
+/*  AST_GPIO_DIR - 0x004 : Direction */
+#define GET_GPIOD_DIR(x)			((x&0xff000000) >> 24)
+#define SET_GPIOD_DIR(x)			(x << 24)
+#define GET_GPIOD_PIN_DIR(x,pin)	((x >> (pin + 24)) & 1)
+#define SET_GPIOD_PIN_DIR(pin)		(1<<(pin + 24))
+#define GET_GPIOC_DIR(x)			((x&0xff0000) >> 16)
+#define SET_GPIOC_DIR(x)			(x << 16)
+#define GET_GPIOC_PIN_DIR(x,pin)	((x >> (pin + 16)) & 1)
+#define SET_GPIOC_PIN_DIR(pin)		(1<<(pin + 16))
+#define GET_GPIOB_DIR(x)			((x&0xff00) >> 8)
+#define SET_GPIOB_DIR(x)			(x << 8)
+#define GET_GPIOB_PIN_DIR(x,pin)	((x >> (pin + 8)) & 1)
+#define SET_GPIOB_PIN_DIR(pin)		(1<<(pin + 8))
+#define GET_GPIOA_DIR(x)			(x&0xff)
+#define SET_GPIOA_DIR(x)			(x)
+#define GET_GPIOA_PIN_DIR(x,pin)	((x >> pin) & 1)
+#define SET_GPIOA_PIN_DIR(pin)		(1<<pin)
+
+/* AST_GPIO_INT_EN - 0x008 : Interrupt Enable */
+#define GET_GPIOD_INT_EN(x)				((x&0xff000000) >> 24)
+#define SET_GPIOD_INT_EN(x)				(x << 24)
+#define GET_GPIOD_PIN_INT_EN(x,pin)		((x >> (pin + 24)) & 1)
+#define SET_GPIOD_PIN_INT_EN(pin)		(1<<(pin + 24))
+#define GET_GPIOC_INT_EN(x)				((x&0xff0000) >> 16)
+#define SET_GPIOC_INT_EN(x)				(x << 16)
+#define GET_GPIOC_PIN_INT_EN(x,pin)		((x >> (pin + 16)) & 1)
+#define SET_GPIOC_PIN_INT_EN(pin)		(1<<(pin + 16))
+#define GET_GPIOB_INT_EN(x)				((x&0xff00) >> 8)
+#define SET_GPIOB_INT_EN(x)				(x << 8)
+#define GET_GPIOB_PIN_INT_EN(x,pin)		((x >> (pin + 8)) & 1)
+#define SET_GPIOB_PIN_INT_EN(pin)			(1<<(pin + 8))
+#define GET_GPIOA_INT_EN(x)				(x&0xff)
+#define SET_GPIOA_INT_EN(x)				(x)
+#define GET_GPIOA_PIN_INT_EN(x,pin)		((x >> pin) & 1)
+#define SET_GPIOA_PIN_INT_EN(pin)		(1<<pin)
+
+/* AST_GPIO_INT_SEN_T0/1/2  - 0x00c/0x010/0x014 : Interrupt Sensitivity Type 0/1/2 */
+#define GET_GPIOD_INT_MODE(x)			((x&0xff000000) >> 24)
+#define SET_GPIOD_INT_MODE(x)			(x << 24)
+#define GET_GPIOD_PIN_INT_MODE(x,pin)		((x >> (pin + 24)) & 1)
+#define SET_GPIOD_PIN_INT_MODE(pin)		(1<<(pin + 24))
+#define GET_GPIOC_INT_MODE(x)			((x&0xff0000) >> 16)
+#define SET_GPIOC_INT_MODE(x)			(x << 16)
+#define GET_GPIOC_PIN_INT_MODE(x,pin)		((x >> (pin + 16)) & 1)
+#define SET_GPIOC_PIN_INT_MODE(pin)		(1<<(pin + 16))
+#define GET_GPIOB_INT_MODE(x)			((x&0xff00) >> 8)
+#define SET_GPIOB_INT_MODE(x)			(x << 16)
+#define GET_GPIOB_PIN_INT_MODE(x,pin)		((x >> (pin + 8)) & 1)
+#define SET_GPIOB_PIN_INT_MODE(pin)		(1<<(pin + 8))
+#define GET_GPIOA_INT_MODE(x)			(x&0xff)
+#define SET_GPIOA_INT_MODE(x)			(x)
+#define GET_GPIOA_PIN_INT_MODE(x,pin)	((x >> pin) & 1)
+#define SET_GPIOA_PIN_INT_MODE(pin)		(1 << pin)
+
+/* AST_GPIO_INT_STS	- 0x018 : Interrupt Status */
+#define GET_GPIOD_INT_STS(x)			((x&0xff000000) >> 24)
+#define SET_GPIOD_INT_STS(x)			(x << 24)
+#define GET_GPIOD_PIN_INT_STS(x,pin)		((x >> (pin + 24)) & 1)
+#define SET_GPIOD_PIN_INT_STS(pin)		(1<<(pin + 24))
+#define GET_GPIOC_INT_STS(x)			((x&0xff0000) >> 16)
+#define SET_GPIOC_INT_STS(x)			(x << 16)
+#define GET_GPIOC_PIN_INT_STS(x,pin)		((x >> (pin + 16)) & 1)
+#define SET_GPIOC_PIN_INT_STS(pin)		(1<<(pin + 16))
+#define GET_GPIOB_INT_STS(x)			((x&0xff00) >> 8)
+#define SET_GPIOB_INT_STS(x)			(x << 16)
+#define GET_GPIOB_PIN_INT_STS(x,pin)		((x >> (pin + 8)) & 1)
+#define SET_GPIOB_PIN_INT_STS(pin)		(1<<(pin + 8))
+#define GET_GPIOA_INT_STS(x)			(x&0xff)
+#define SET_GPIOA_INT_STS(x)			(x)
+#define GET_GPIOA_PIN_INT_STS(x,pin)	((x >> pin) & 1)
+#define SET_GPIOA_PIN_INT_STS(pin)		(1 << pin)
+
+/* AST_GPIO_RST_TOR - 0x01c : Reset Tolerant */
+#define GET_GPIOD_RST_EN(x)				((x&0xff000000) >> 24)
+#define SET_GPIOD_RST_EN(x)				(x << 24)
+#define GET_GPIOD_PIN_RST_EN(x,pin)		((x >> (pin + 24)) & 1)
+#define SET_GPIOD_PIN_RST_EN(pin)		(1<<(pin + 24))
+#define GET_GPIOC_RST_EN(x)				((x&0xff0000) >> 16)
+#define SET_GPIOC_RST_EN(x)				(x << 16)
+#define GET_GPIOC_PIN_RST_EN(x,pin)		((x >> (pin + 16)) & 1)
+#define SET_GPIOC_PIN_RST_EN(pin)		(1<<(pin + 16))
+#define GET_GPIOB_RST_EN(x)				((x&0xff00) >> 8)
+#define SET_GPIOB_RST_EN(x)				(x << 16)
+#define GET_GPIOB_PIN_RST_EN(x,pin)		((x >> (pin + 8)) & 1)
+#define SET_GPIOB_PIN_RST_EN(pin)		(1<<(pin + 8))
+#define GET_GPIOA_RST_EN(x)				(x&0xff)
+#define SET_GPIOA_RST_EN(x)				(x)
+#define GET_GPIOA_PIN_RST_EN(x,pin)		((x >> pin) & 1)
+#define SET_GPIOA_PIN_RST_EN(pin)		(1 << pin)
+
+/* AST_EXT_GPIO_DATA - 0x020 :  E/F/G/H Data Vale  */
+#define GET_GPIOH_DATA(x)			((x&0xff000000) >> 24)
+#define SET_GPIOH_DATA(x)			(x << 24)
+#define GET_GPIOH_PIN_DATA(x,pin)	((x >> (pin + 24)) & 1)
+#define SET_GPIOH_PIN_DATA(pin)		(1<<(pin + 24))
+#define GET_GPIOG_DATA(x)			((x&0xff0000) >> 16)
+#define SET_GPIOG_DATA(x)			(x << 16)
+#define GET_GPIOG_PIN_DATA(x,pin)	((x >> (pin + 16)) & 1)
+#define SET_GPIOG_PIN_DATA(pin)		(1<<(pin + 16))
+#define GET_GPIOF_DATA(x)			((x&0xff00) >> 8)
+#define SET_GPIOF_DATA(x)			(x << 8)
+#define GET_GPIOF_PIN_DATA(x,pin)	((x >> (pin + 8)) & 1)
+#define SET_GPIOF_PIN_DATA(pin)		(1<<(pin + 8))
+#define GET_GPIOE_DATA(x)			(x&0xff)
+#define SET_GPIOE_DATA(x)			(x)
+#define GET_GPIOE_PIN_DATA(x,pin)	((x >> pin) & 1)
+#define SET_GPIOE_PIN_DATA(pin)		(1<<pin)
+
+/* AST_EXT_GPIO_DIR		 - 0x024 : */
+#define GET_GPIOH_DIR(x)			((x&0xff000000) >> 24)
+#define SET_GPIOH_DIR(x)			(x << 24)
+#define GET_GPIOH_PIN_DIR(x,pin)	((x >> (pin + 24)) & 1)
+#define SET_GPIOH_PIN_DIR(pin)		(1<<(pin + 24))
+#define GET_GPIOG_DIR(x)			((x&0xff0000) >> 16)
+#define SET_GPIOG_DIR(x)			(x << 16)
+#define GET_GPIOG_PIN_DIR(x,pin)	((x >> (pin + 16)) & 1)
+#define SET_GPIOG_PIN_DIR(pin)		(1<<(pin + 16))
+#define GET_GPIOF_DIR(x)			((x&0xff00) >> 8)
+#define SET_GPIOF_DIR(x)			(x << 8)
+#define GET_GPIOF_PIN_DIR(x,pin)	((x >> (pin + 8)) & 1)
+#define SET_GPIOF_PIN_DIR(pin)		(1<<(pin + 8))
+#define GET_GPIOE_DIR(x)			(x&0xff)
+#define SET_GPIOE_DIR(x)			(x)
+#define GET_GPIOE_PIN_DIR(x,pin)	((x >> pin) & 1)
+#define SET_GPIOE_PIN_DIR(pin)		(1<<pin)
+
+/* AST_EXT_GPIO_INT_EN	 - 0x028 */
+#define GET_GPIOH_INT_EN(x)				((x&0xff000000) >> 24)
+#define SET_GPIOH_INT_EN(x)				(x << 24)
+#define GET_GPIOH_PIN_INT_EN(x,pin)		((x >> (pin + 24)) & 1)
+#define SET_GPIOH_PIN_INT_EN(pin)		(1<<(pin + 24))
+#define GET_GPIOG_INT_EN(x)				((x&0xff0000) >> 16)
+#define SET_GPIOG_INT_EN(x)				(x << 16)
+#define GET_GPIOG_PIN_INT_EN(x,pin)		((x >> (pin + 16)) & 1)
+#define SET_GPIOG_PIN_INT_EN(pin)		(1<<(pin + 16))
+#define GET_GPIOF_INT_EN(x)				((x&0xff00) >> 8)
+#define SET_GPIOF_INT_EN(x)				(x << 8)
+#define GET_GPIOF_PIN_INT_EN(x,pin)		((x >> (pin + 8)) & 1)
+#define SET_GPIOF_PIN_INT_EN(pin)			(1<<(pin + 8))
+#define GET_GPIOE_INT_EN(x)				(x&0xff)
+#define SET_GPIOE_INT_EN(x)				(x)
+#define GET_GPIOE_PIN_INT_EN(x,pin)		((x >> pin) & 1)
+#define SET_GPIOE_PIN_INT_EN(pin)		(1<<pin)
+
+/* AST_EXT_GPIO_INT_SEN_T0/1/2	- 0x02c/0x30/0x34 :  */
+/* AST_EXT_GPIO_INT_STS					0x038 */
+/* AST_EXT_GPIO_RST_TOR				0x03c */
+
+/* AST_GPIO_DEBOUNCE_SET1 -	0x040 : Debounce Setting #1 */
+#define GET_GPIO3_DEBOUNCE(x)				((x&0xff000000) >> 24)
+#define SET_GPIO3_DEBOUNCE(x)				(x << 24)
+#define GET_GPIO3_PIN_DEBOUNCE(x,pin)		((x >> (pin + 24)) & 1)
+#define SET_GPIO3_PIN_DEBOUNCE(pin)		(1<<(pin + 24))
+#define GET_GPIO2_DEBOUNCE(x)				((x&0xff0000) >> 16)
+#define SET_GPIO2_DEBOUNCE(x)				(x << 16)
+#define GET_GPIO2_PIN_DEBOUNCE(x,pin)		((x >> (pin + 16)) & 1)
+#define SET_GPIO2_PIN_DEBOUNCE(pin)		(1<<(pin + 16))
+#define GET_GPIO1_DEBOUNCE(x)				((x&0xff00) >> 8)
+#define SET_GPIO1_DEBOUNCE(x)				(x << 8)
+#define GET_GPIO1_PIN_DEBOUNCE(x,pin)		((x >> (pin + 8)) & 1)
+#define SET_GPIO1_PIN_DEBOUNCE(pin)			(1<<(pin + 8))
+#define GET_GPIO0_DEBOUNCE(x)				(x&0xff)
+#define SET_GPIO0_DEBOUNCE(x)				(x)
+#define GET_GPIO0_PIN_DEBOUNCE(x,pin)		((x >> pin) & 1)
+#define SET_GPIO0_PIN_DEBOUNCE(pin)		(1<<pin)
+
+
+#endif /* __ASM_ARCH_REGS_GPIO_H */
\ No newline at end of file
diff --git a/arch/arm/plat-aspeed/include/plat/regs-iic.h b/arch/arm/plat-aspeed/include/plat/regs-iic.h
new file mode 100644
index 0000000..14db73c
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-iic.h
@@ -0,0 +1,286 @@
+/* arch/arm/plat-aspeed/include/mach/regs-iic.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED I2C Controller
+*/
+
+#ifndef __ASM_ARCH_REGS_IIC_H
+#define __ASM_ARCH_REGS_IIC_H __FILE__
+
+#ifdef CONFIG_ARCH_AST1010
+#define AST_I2C_DMA_SIZE 512
+#else
+#define AST_I2C_DMA_SIZE 4096
+#endif
+
+#define AST_I2C_PAGE_SIZE 256
+
+#if defined(CONFIG_ARCH_AST2300)
+#define MASTER_XFER_MODE			BUFF_MODE
+#define SLAVE_XFER_MODE				BYTE_MODE
+#define NUM_BUS 9
+#elif defined(CONFIG_ARCH_AST2400)
+#define MASTER_XFER_MODE			BUFF_MODE
+#define SLAVE_XFER_MODE				BYTE_MODE
+#define NUM_BUS 14
+#elif defined(CONFIG_ARCH_AST1010)
+#define MASTER_XFER_MODE			BYTE_MODE
+#define SLAVE_XFER_MODE				BYTE_MODE
+#define NUM_BUS 15
+#elif defined(CONFIG_ARCH_AST1520) || defined(CONFIG_ARCH_AST3200) || defined(CONFIG_ARCH_AST2500)
+#define MASTER_XFER_MODE			BYTE_MODE
+#define SLAVE_XFER_MODE				BYTE_MODE
+#define NUM_BUS 4
+#else
+#err "NO define NUM_BUS"
+#endif
+
+#if defined(CONFIG_ARCH_AST1070)
+#define AST_CI2C_GLOBAL_REG			0x00
+#define AST_CI2C_DEVICE1			0x40
+#define AST_CI2C_DEVICE2			0x80
+#define AST_CI2C_DEVICE3			0xc0
+#define AST_CI2C_DEVICE4			0x100
+#define AST_CI2C_DEVICE5			0x140
+#define AST_CI2C_DEVICE6			0x180
+#define AST_CI2C_DEVICE7			0x1c0
+#define AST_CI2C_DEVICE8			0x200
+#endif
+
+/*AST I2C Register Definition */
+#if defined(CONFIG_ARCH_AST2400) || defined(CONFIG_AST2400_BMC)
+#define AST_I2C_POOL_BUFF_2048	
+#define AST_I2C_GLOBAL_REG		0x00
+#define AST_I2C_DEVICE1			0x40
+#define AST_I2C_DEVICE2			0x80
+#define AST_I2C_DEVICE3			0xc0
+#define AST_I2C_DEVICE4			0x100
+#define AST_I2C_DEVICE5			0x140
+#define AST_I2C_DEVICE6			0x180
+#define AST_I2C_DEVICE7			0x1c0
+#define AST_I2C_BUFFER_POOL2	0x200
+#define AST_I2C_DEVICE8			0x300
+#define AST_I2C_DEVICE9			0x340
+#define AST_I2C_DEVICE10		0x380
+#define AST_I2C_DEVICE11		0x3c0
+#define AST_I2C_DEVICE12		0x400
+#define AST_I2C_DEVICE13		0x440
+#define AST_I2C_DEVICE14		0x480
+#define AST_I2C_BUFFER_POOL1	0x800
+
+#elif defined(CONFIG_ARCH_AST2300)
+#define AST_I2C_POOL_BUFF_256
+#define AST_I2C_GLOBAL_REG		0x00
+#define AST_I2C_DEVICE1			0x40
+#define AST_I2C_DEVICE2			0x80
+#define AST_I2C_DEVICE3			0xc0
+#define AST_I2C_DEVICE4			0x100
+#define AST_I2C_DEVICE5			0x140
+#define AST_I2C_DEVICE6			0x180
+#define AST_I2C_DEVICE7			0x1c0
+#define AST_I2C_BUFFER_POOL2	0x200
+#define AST_I2C_DEVICE8			0x300
+#define AST_I2C_DEVICE9			0x340
+#elif defined(CONFIG_ARCH_AST1010)
+#define AST_I2C_GLOBAL_REG		0x00
+#define AST_I2C_DEVICE1			0x40
+#define AST_I2C_DEVICE2			0x80
+#define AST_I2C_DEVICE3			0xc0
+#define AST_I2C_DEVICE4			0x100
+#define AST_I2C_DEVICE5			0x140
+#define AST_I2C_DEVICE6			0x180
+#define AST_I2C_DEVICE7			0x1c0
+#define AST_I2C_DEVICE8			0x200
+#define AST_I2C_DEVICE9			0x240
+#define AST_I2C_DEVICE10		0x280
+#define AST_I2C_DEVICE11		0x2c0
+#define AST_I2C_DEVICE12		0x300
+#define AST_I2C_DEVICE13		0x340
+#define AST_I2C_DEVICE14		0x380
+#define AST_I2C_DEVICE15		0x3c0
+#elif defined(CONFIG_ARCH_AST1520) || defined(CONFIG_ARCH_AST3200) || defined(CONFIG_ARCH_AST2500)
+#define AST_I2C_GLOBAL_REG		0x00
+#define AST_I2C_DEVICE1			0x40
+#define AST_I2C_DEVICE2			0x80
+#define AST_I2C_DEVICE3			0xc0
+#define AST_I2C_DEVICE4			0x100
+#else
+#err "NO define for I2C"
+#endif
+
+
+
+/* I2C Register */
+#define  I2C_FUN_CTRL_REG    				0x00
+#define  I2C_AC_TIMING_REG1         		0x04
+#define  I2C_AC_TIMING_REG2         		0x08
+#define  I2C_INTR_CTRL_REG					0x0c
+#define  I2C_INTR_STS_REG					0x10
+#define  I2C_CMD_REG						0x14
+#define  I2C_DEV_ADDR_REG					0x18
+#define  I2C_BUF_CTRL_REG					0x1c
+#define  I2C_BYTE_BUF_REG					0x20
+#define  I2C_DMA_BASE_REG					0x24
+#define  I2C_DMA_LEN_REG					0x28
+
+
+/* Gloable Register Definition */
+/* 0x00 : I2C Interrupt Status Register  */
+/* 0x08 : I2C Interrupt Target Assignment  */
+#if defined(CONFIG_ARCH_AST2400)
+#define AST_I2CG_INTR14 		(0x1 << 13)
+#define AST_I2CG_INTR13 		(0x1 << 12)
+#define AST_I2CG_INTR12 		(0x1 << 11)
+#define AST_I2CG_INTR11 		(0x1 << 10)
+#define AST_I2CG_INTR10 		(0x1 << 9)
+#elif defined(CONFIG_ARCH_AST1010)
+#define AST_I2CG_INTR14 		(0x1 << 13)
+#define AST_I2CG_INTR13 		(0x1 << 12)
+#define AST_I2CG_INTR12 		(0x1 << 11)
+#define AST_I2CG_INTR11 		(0x1 << 10)
+#define AST_I2CG_INTR10 		(0x1 << 9)
+#endif
+#define AST_I2CG_INTR09 		(0x1 << 8)
+#define AST_I2CG_INTR08 		(0x1 << 7)
+#define AST_I2CG_INTR07 		(0x1 << 6)
+#define AST_I2CG_INTR06	 		(0x1 << 5)
+#define AST_I2CG_INTR05	 		(0x1 << 4)
+#define AST_I2CG_INTR04 		(0x1 << 3)
+#define AST_I2CG_INTR03	 		(0x1 << 2)
+#define AST_I2CG_INTR02	 		(0x1 << 1)
+#define AST_I2CG_INTR01	 		(0x1 )
+
+/* Device Register Definition */
+/* 0x00 : I2CD Function Control Register  */
+#define AST_I2CD_BUFF_SEL_MASK				(0x7 << 20)
+#define AST_I2CD_BUFF_SEL(x) 				(x << 20)		// page 0 ~ 7
+#define AST_I2CD_M_SDA_LOCK_EN			(0x1 << 16)
+#define AST_I2CD_MULTI_MASTER_DIS			(0x1 << 15)
+#define AST_I2CD_M_SCL_DRIVE_EN		(0x1 << 14)
+#define AST_I2CD_MSB_STS					(0x1 << 9)
+#define AST_I2CD_SDA_DRIVE_1T_EN			(0x1 << 8)
+#define AST_I2CD_M_SDA_DRIVE_1T_EN		(0x1 << 7)
+#define AST_I2CD_M_HIGH_SPEED_EN		(0x1 << 6)
+#define AST_I2CD_DEF_ADDR_EN				(0x1 << 5)
+#define AST_I2CD_DEF_ALERT_EN				(0x1 << 4)
+#define AST_I2CD_DEF_ARP_EN					(0x1 << 3)
+#define AST_I2CD_DEF_GCALL_EN				(0x1 << 2)
+#define AST_I2CD_SLAVE_EN					(0x1 << 1)
+#define AST_I2CD_MASTER_EN					(0x1 )
+
+/* 0x04 : I2CD Clock and AC Timing Control Register #1 */
+#define AST_I2CD_tBUF						(0x1 << 28) 	// 0~7 
+#define AST_I2CD_tHDSTA						(0x1 << 24)		// 0~7 
+#define AST_I2CD_tACST						(0x1 << 20)		// 0~7 
+#define AST_I2CD_tCKHIGH					(0x1 << 16)		// 0~7 
+#define AST_I2CD_tCKLOW						(0x1 << 12)		// 0~7 
+#define AST_I2CD_tHDDAT						(0x1 << 10)		// 0~7 
+#define AST_I2CD_CLK_TO_BASE_DIV			(0x1 << 8)		// 0~3
+#define AST_I2CD_CLK_BASE_DIV				(0x1 )			// 0~0xf
+
+/* 0x08 : I2CD Clock and AC Timing Control Register #2 */
+#define AST_I2CD_tTIMEOUT					(0x1 )			// 0~7
+#define AST_NO_TIMEOUT_CTRL					0x0
+
+
+/* 0x0c : I2CD Interrupt Control Register  */
+#define AST_I2CD_SDA_DL_TO_INTR_EN					(0x1 << 14)		
+#define AST_I2CD_BUS_RECOVER_INTR_EN				(0x1 << 13)		
+#define AST_I2CD_SMBUS_ALT_INTR_EN					(0x1 << 12)		
+#define AST_I2CD_SLAVE_MATCH_INTR_EN				(0x1 << 7)		
+#define AST_I2CD_SCL_TO_INTR_EN						(0x1 << 6)		
+#define AST_I2CD_ABNORMAL_INTR_EN					(0x1 << 5)		
+#define AST_I2CD_NORMAL_STOP_INTR_EN				(0x1 << 4)
+#define AST_I2CD_ARBIT_LOSS_INTR_EN					(0x1 << 3)		
+#define AST_I2CD_RX_DOWN_INTR_EN					(0x1 << 2)		
+#define AST_I2CD_TX_NAK_INTR_EN						(0x1 << 1)		
+#define AST_I2CD_TX_ACK_INTR_EN						(0x1 )		
+
+/* 0x10 : I2CD Interrupt Status Register   : WC */
+#define AST_I2CD_INTR_STS_SDA_DL_TO					(0x1 << 14)		
+#define AST_I2CD_INTR_STS_BUS_RECOVER				(0x1 << 13)		
+#define AST_I2CD_INTR_STS_SMBUS_ALT					(0x1 << 12)		
+#define AST_I2CD_INTR_STS_SMBUS_ARP_ADDR			(0x1 << 11)		
+#define AST_I2CD_INTR_STS_SMBUS_DEV_ALT				(0x1 << 10)		
+#define AST_I2CD_INTR_STS_SMBUS_DEF_ADDR			(0x1 << 9)		
+#define AST_I2CD_INTR_STS_GCALL_ADDR				(0x1 << 8)		
+#define AST_I2CD_INTR_STS_SLAVE_MATCH				(0x1 << 7)		
+#define AST_I2CD_INTR_STS_SCL_TO					(0x1 << 6)		
+#define AST_I2CD_INTR_STS_ABNORMAL					(0x1 << 5)		
+#define AST_I2CD_INTR_STS_NORMAL_STOP				(0x1 << 4)
+#define AST_I2CD_INTR_STS_ARBIT_LOSS				(0x1 << 3)
+#define AST_I2CD_INTR_STS_RX_DOWN					(0x1 << 2)		
+#define AST_I2CD_INTR_STS_TX_NAK					(0x1 << 1)		
+#define AST_I2CD_INTR_STS_TX_ACK					(0x1 )		
+
+/* 0x14 : I2CD Command/Status Register   */
+#define AST_I2CD_SDA_OE					(0x1 << 28)
+#define AST_I2CD_SDA_O					(0x1 << 27)		
+#define AST_I2CD_SCL_OE					(0x1 << 26)		
+#define AST_I2CD_SCL_O					(0x1 << 25)		
+#define AST_I2CD_TX_TIMING				(0x1 << 24)		// 0 ~3
+#define AST_I2CD_TX_STATUS				(0x1 << 23)		
+// Tx State Machine 
+#define AST_I2CD_IDLE	 				0x0
+#define AST_I2CD_MACTIVE				0x8
+#define AST_I2CD_MSTART					0x9
+#define AST_I2CD_MSTARTR				0xa
+#define AST_I2CD_MSTOP					0xb
+#define AST_I2CD_MTXD					0xc
+#define AST_I2CD_MRXACK					0xd
+#define AST_I2CD_MRXD 					0xe
+#define AST_I2CD_MTXACK 				0xf
+#define AST_I2CD_SWAIT					0x1
+#define AST_I2CD_SRXD 					0x4
+#define AST_I2CD_STXACK 				0x5
+#define AST_I2CD_STXD					0x6
+#define AST_I2CD_SRXACK 				0x7
+#define AST_I2CD_RECOVER 				0x3
+
+#define AST_I2CD_SCL_LINE_STS				(0x1 << 18)		
+#define AST_I2CD_SDA_LINE_STS				(0x1 << 17)		
+#define AST_I2CD_BUS_BUSY_STS				(0x1 << 16)		
+#define AST_I2CD_SDA_OE_OUT_DIR				(0x1 << 15)		
+#define AST_I2CD_SDA_O_OUT_DIR				(0x1 << 14)		
+#define AST_I2CD_SCL_OE_OUT_DIR				(0x1 << 13)		
+#define AST_I2CD_SCL_O_OUT_DIR				(0x1 << 12)		
+#define AST_I2CD_BUS_RECOVER_CMD_EN			(0x1 << 11)		
+#define AST_I2CD_S_ALT_EN				(0x1 << 10)		
+// 0 : DMA Buffer, 1: Pool Buffer
+//AST1070 DMA register 
+#define AST_I2CD_RX_DMA_ENABLE				(0x1 << 9)		
+#define AST_I2CD_TX_DMA_ENABLE				(0x1 << 8)		
+
+/* Command Bit */
+#define AST_I2CD_RX_BUFF_ENABLE				(0x1 << 7)		
+#define AST_I2CD_TX_BUFF_ENABLE				(0x1 << 6)		
+#define AST_I2CD_M_STOP_CMD					(0x1 << 5)		
+#define AST_I2CD_M_S_RX_CMD_LAST			(0x1 << 4)		
+#define AST_I2CD_M_RX_CMD					(0x1 << 3)		
+#define AST_I2CD_S_TX_CMD					(0x1 << 2)		
+#define AST_I2CD_M_TX_CMD					(0x1 << 1)		
+#define AST_I2CD_M_START_CMD				(0x1 )		
+
+/* 0x18 : I2CD Slave Device Address Register   */
+
+/* 0x1C : I2CD Pool Buffer Control Register   */
+#define AST_I2CD_RX_BUF_ADDR_GET(x)				((x>> 24)& 0xff)
+#define AST_I2CD_RX_BUF_END_ADDR_SET(x)			(x << 16)		
+#define AST_I2CD_TX_DATA_BUF_END_SET(x)			((x&0xff) << 8)		
+#define AST_I2CD_TX_DATA_BUF_GET(x)			((x >>8) & 0xff)		
+#define AST_I2CD_BUF_BASE_ADDR_SET(x)			(x & 0x3f)		
+
+/* 0x20 : I2CD Transmit/Receive Byte Buffer Register   */
+#define AST_I2CD_GET_MODE(x)					((x >> 8) & 0x1)		
+
+#define AST_I2CD_RX_BYTE_BUFFER					(0xff << 8)		
+#define AST_I2CD_TX_BYTE_BUFFER					(0xff )		
+
+
+#endif /* __ASM_ARCH_REGS_IIC_H */
diff --git a/arch/arm/plat-aspeed/include/plat/regs-intr.h b/arch/arm/plat-aspeed/include/plat/regs-intr.h
new file mode 100644
index 0000000..cea0132
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-intr.h
@@ -0,0 +1,74 @@
+/* arch/arm/mach-aspeed/include/mach/regs-intr.h
+ *
+ * Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *   History      : 
+ *    1. 2012/08/15 Ryan Chen Create
+ * 
+********************************************************************************/
+#ifndef __ASPEED_AST_INTR_H
+#define __ASPEED_AST_INTR_H                     1
+
+#ifndef __ASSEMBLY__
+#include <asm/io.h>
+#endif
+//============== INTERRUPT========================================
+#include <mach/platform.h>
+#include <mach/irqs.h>
+#include <plat/aspeed.h>
+
+/*
+ * VIC Register (VA)
+ */
+
+#define VIC_BASE_VA              		IO_ADDRESS(AST_VIC_BASE) 
+
+#if defined(NEW_VIC)
+//New Mappling
+
+#define AST_IRQ_STS(x)				(VIC_BASE_VA + 0x80 + (x*0x04))
+#define AST_FIQ_STS(x)				(VIC_BASE_VA + 0x88 + (x*0x04))
+#define AST_RAW_STS(x)				(VIC_BASE_VA + 0x90 + (x*0x04))
+#define AST_INTR_SEL(x)				(VIC_BASE_VA + 0x98 + (x*0x04))
+#define AST_INTR_EN(x)				(VIC_BASE_VA + 0xA0 + (x*0x04))
+#define AST_INTR_DIS(x)				(VIC_BASE_VA + 0xA8 + (x*0x04))
+#define AST_INTR_SW_EN(x)			(VIC_BASE_VA + 0xB0 + (x*0x04))
+#define AST_INTR_SW_CLR(x)			(VIC_BASE_VA + 0xB8 + (x*0x04))
+#define AST_INTR_SENSE(x)			(VIC_BASE_VA + 0xC0 + (x*0x04))
+#define AST_INTR_BOTH_EDGE(x)		(VIC_BASE_VA + 0xC8 + (x*0x04))
+#define AST_INTR_EVENT(x)			(VIC_BASE_VA + 0xD0 + (x*0x04))
+#define AST_INTR_EDGE_CLR(x)		(VIC_BASE_VA + 0xD8 + (x*0x04))
+#define AST_INTR_EDGE_STS(x)		(VIC_BASE_VA + 0xE0 + (x*0x04))
+
+#else
+
+//Legacy Maping 
+
+#define AST_IRQ_STS(x)				(VIC_BASE_VA + 0x00)
+#define AST_FIQ_STS(x)				(VIC_BASE_VA + 0x04)
+#define AST_RAW_STS(x)				(VIC_BASE_VA + 0x08)
+#define AST_INTR_SEL(x)				(VIC_BASE_VA + 0x0C)
+#define AST_INTR_EN(x)				(VIC_BASE_VA + 0x10)
+#define AST_INTR_DIS(x)				(VIC_BASE_VA + 0x14)
+#define AST_INTR_SW_EN(x)			(VIC_BASE_VA + 0x18)
+#define AST_INTR_SW_CLR(x)			(VIC_BASE_VA + 0x1C)
+#define AST_INTR_SENSE(x)			(VIC_BASE_VA + 0x24)
+#define AST_INTR_BOTH_EDGE(x)		(VIC_BASE_VA + 0x28)
+#define AST_INTR_EVENT(x)			(VIC_BASE_VA + 0x2C)
+#define AST_INTR_EDGE_CLR(x)		(VIC_BASE_VA + 0x38)
+#endif
+
+#define IRQ_SET_LEVEL_TRIGGER(x, irq_no)   *((volatile unsigned long*)AST_INTR_SENSE(x)) |= 1 << (irq_no)
+#define IRQ_SET_EDGE_TRIGGER(x, irq_no)    *((volatile unsigned long*)AST_INTR_SENSE(x)) &= ~(1 << (irq_no))
+#define IRQ_SET_RISING_EDGE(x, irq_no)     *((volatile unsigned long*)AST_INTR_EVENT(x)) |= 1 << (irq_no)
+#define IRQ_SET_FALLING_EDGE(x, irq_no)    *((volatile unsigned long*)AST_INTR_EVENT(x)) &= ~(1 << (irq_no))
+#define IRQ_SET_HIGH_LEVEL(x,irq_no)      *((volatile unsigned long*)AST_INTR_EVENT(x)) |= 1 << (irq_no)
+#define IRQ_SET_LOW_LEVEL(x, irq_no)       *((volatile unsigned long*)AST_INTR_EVENT(x)) &= ~(1 << (irq_no))
+#define IRQ_EDGE_CLEAR(x, irq_no)          *((volatile unsigned long*)AST_INTR_EDGE_CLR(x)) |= 1 << (irq_no)
+
+#endif
+
diff --git a/arch/arm/plat-aspeed/include/plat/regs-jtag.h b/arch/arm/plat-aspeed/include/plat/regs-jtag.h
new file mode 100644
index 0000000..7df385d
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-jtag.h
@@ -0,0 +1,65 @@
+/* arch/arm/plat-aspeed/include/mach/regs-jtag.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED JTAG Controller
+*/
+
+#define AST_JTAG_DATA			0x00
+#define AST_JTAG_INST			0x04
+#define AST_JTAG_CTRL			0x08
+#define AST_JTAG_ISR			0x0C
+#define AST_JTAG_SW				0x10
+#define AST_JTAG_TCK			0x14
+#define AST_JTAG_IDLE			0x18
+
+/* AST_JTAG_CTRL - 0x08 : Engine Control */
+#define JTAG_ENG_EN				(0x1 << 31)
+#define JTAG_ENG_OUT_EN			(0x1 << 30)
+#define JTAG_FORCE_TMS			(0x1 << 29)
+
+#define JTAG_IR_UPDATE			(0x1 << 26)	//AST2500 only
+#define JTAG_INST_LEN_MASK		(0x3f << 20)
+#define JTAG_SET_INST_LEN(x)	(x << 20)
+#define JTAG_SET_INST_MSB		(0x1 << 19)
+#define JTAG_TERMINATE_INST		(0x1 << 18)
+#define JTAG_LAST_INST			(0x1 << 17)
+#define JTAG_INST_EN			(0x1 << 16)
+#define JTAG_DATA_LEN_MASK		(0x3f << 4)
+
+#define JTAG_DR_UPDATE			(0x1 << 10)	//AST2500 only
+#define JTAG_DATA_LEN(x)		(x << 4)
+#define JTAG_SET_DATA_MSB		(0x1 << 3)
+#define JTAG_TERMINATE_DATA		(0x1 << 2)
+#define JTAG_LAST_DATA			(0x1 << 1)
+#define JTAG_DATA_EN			(0x1)
+
+/* AST_JTAG_ISR	- 0x0C : INterrupt status and enable */
+#define JTAG_INST_PAUSE			(0x1 << 19)
+#define JTAG_INST_COMPLETE		(0x1 << 18)
+#define JTAG_DATA_PAUSE			(0x1 << 17)
+#define JTAG_DATA_COMPLETE		(0x1 << 16)
+
+#define JTAG_INST_PAUSE_EN		(0x1 << 3)
+#define JTAG_INST_COMPLETE_EN	(0x1 << 2)
+#define JTAG_DATA_PAUSE_EN		(0x1 << 1)
+#define JTAG_DATA_COMPLETE_EN	(0x1)
+
+
+/* AST_JTAG_SW	- 0x10 : Software Mode and Status */
+#define JTAG_SW_MODE_EN			(0x1 << 19)
+#define JTAG_SW_MODE_TCK		(0x1 << 18)
+#define JTAG_SW_MODE_TMS		(0x1 << 17)
+#define JTAG_SW_MODE_TDIO		(0x1 << 16)
+//
+#define JTAG_STS_INST_PAUSE		(0x1 << 2)
+#define JTAG_STS_DATA_PAUSE		(0x1 << 1)
+#define JTAG_STS_ENG_IDLE		(0x1)
+
+/*  AST_JTAG_IDLE - 0x18 : Ctroller set for go to IDLE */
+#define JTAG_GO_IDLE			(0x1)
diff --git a/arch/arm/plat-aspeed/include/plat/regs-lpc.h b/arch/arm/plat-aspeed/include/plat/regs-lpc.h
new file mode 100644
index 0000000..f4523d7
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-lpc.h
@@ -0,0 +1,215 @@
+/* arch/arm/plat-aspeed/include/mach/regs-lpc.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED LPC Controller
+*/
+
+#ifndef __AST_LPC_H_
+#define __AST_LPC_H_
+
+#define AST_LPC_HICR0				0x000
+#define	AST_LPC_HICR1				0x004
+#define AST_LPC_HICR2				0x008	/* Host Interface Control Register 2 */
+#define AST_LPC_HICR3				0x00C
+#define AST_LPC_HICR4				0x010
+#define AST_LPC_LADR3H				0x014
+#define AST_LPC_LADR3L				0x018
+#define AST_LPC_LADR12H				0x01C
+#define AST_LPC_LADR12L				0x020
+#define AST_LPC_IDR1				0x024
+#define AST_LPC_IDR2				0x028
+#define AST_LPC_IDR3				0x02C
+#define AST_LPC_ODR1				0x030
+#define AST_LPC_ODR2				0x034
+#define AST_LPC_ODR3				0x038
+#define AST_LPC_STR1				0x03C
+#define AST_LPC_STR2				0x040
+#define AST_LPC_STR3				0x044
+#define AST_LPC_BTR0				0x048
+#define AST_LPC_BTR1				0x04C
+#define AST_LPC_BTCSR0				0x050
+#define AST_LPC_BTCSR1				0x054
+#define AST_LPC_BTCR				0x058
+#define AST_LPC_BTDTR				0x05C
+#define AST_LPC_BTIMSR				0x060
+#define AST_LPC_BTFVSR0				0x064
+#define AST_LPC_BTFVSR1				0x068
+#define AST_LPC_SIRQCR0				0x06C
+#define AST_LPC_SIRQCR1				0x070
+#define AST_LPC_SIRQCR2				0x074
+#define AST_LPC_SIRQCR3				0x078
+
+//////
+#define AST_LPC_HICR5				0x080	/* LPC Host interface Control Register 5 */
+#define AST_LPC_HICR6				0x084	/* LPC Host Interface Control Register 6 */
+#define AST_LPC_HICR7				0x088
+#define AST_LPC_HICR8				0x08C
+#define AST_LPC_SNPWADR				0x090	/* LPC Snoop Address Register */
+#define AST_LPC_SNPWDR				0x094	/* LPC SNoop Data Register */
+#define AST_LPC_HICR9				0x098
+#define AST_LPC_HICRA				0x09C
+#define AST_LPC_LHCR0				0x0A0
+#define AST_LPC_LHCR1				0x0A4
+#define AST_LPC_LHCR2				0x0A8
+#define AST_LPC_LHCR3				0x0AC
+#define AST_LPC_LHCR4				0x0B0
+#define AST_LPC_LHCR5				0x0B4
+#define AST_LPC_LHCR6				0x0B8
+#define AST_LPC_LHCR7				0x0BC
+#define AST_LPC_LHCR8				0x0C0
+#define AST_LPC_PCCR6				0x0C4
+#define AST_LPC_LHCRA				0x0C8
+#define AST_LPC_LHCRB				0x0CC
+
+
+#define AST_LPC_PCCR4				0x0D0	/* Post Code Control Regiter 4 */
+#define AST_LPC_PCCR5				0x0D4	/* Post Code Control Regiter 5 */
+
+#define AST_LPC_HICRB				0x0D8
+#define AST_LPC_HICRC				0x0DC
+#define AST_LPC_HISR0				0x0E0
+#define AST_LPC_HISR1				0x0E4
+#define AST_LPC_LADR4				0x0E8
+#define AST_LPC_IDR4				0x0EC
+#define AST_LPC_ODR4				0x0F0
+#define AST_LPC_STR4				0x0F4
+#define AST_LPC_LSADR12				0x0F8
+#define AST_LPC_IDR5				0x0FC
+#define AST_LPC_ODR5				0x100
+#define AST_LPC_STR5				0x104
+
+
+
+#define AST_LPC_PCCR0				0x130	/*Post Code Contol Register 0 */
+#define AST_LPC_PCCR1				0x134	/*Post Code Contol Register 1 */
+#define AST_LPC_PCCR2				0x138	/*Post Code Contol Register 2 */
+#define AST_LPC_PCCR3				0x13C	/*Post Code Contol Register 3 */
+
+
+#define AST_LPC_IBTCR0				0x140
+#define AST_LPC_IBTCR1				0x144
+#define AST_LPC_IBTCR2				0x148
+#define AST_LPC_IBTCR3				0x14C
+#define AST_LPC_IBTCR4				0x150
+#define AST_LPC_IBTCR5				0x154
+#define AST_LPC_IBTCR6				0x158
+#define AST_LPC_SRUART1				0x15C
+#define AST_LPC_SRUART2				0x160
+#define AST_LPC_SRUART3				0x164
+#define AST_LPC_SRUART4				0x168
+#define AST_LPC_SCR0SIO				0x16C
+#define AST_LPC_SCR0SI1				0x170
+#define AST_LPC_SCR0SI2				0x174
+#define AST_LPC_SCR0SI3				0x17C
+
+#define AST_LPC_SWCR0300			0x180
+#define AST_LPC_SWCR0704			0x184
+#define AST_LPC_SWCR0B08			0x188
+#define AST_LPC_SWCR0F0C			0x18C
+#define AST_LPC_SWCR1310			0x190
+#define AST_LPC_SWCR1714			0x194
+#define AST_LPC_SWCR1B18			0x198
+#define AST_LPC_SWCR1F1C			0x19C
+#define AST_LPC_ACPIE3E0			0x1A0
+#define AST_LPC_ACPIC1C0			0x1A4
+#define AST_LPC_ACPIB3B0			0x1A8
+#define AST_LPC_ACPIB7B4			0x1AC
+
+/* AST_LPC_HICR0				0x000 		*/
+#define LPC_LPC3_EN					(1 << 7)
+#define LPC_LPC2_EN					(1 << 6)
+#define LPC_LPC1_EN					(1 << 5)
+
+#define LPC_SDWNE					(1 << 3)
+#define LPC_PMEE					(1 << 2)
+
+/* AST_LPC_HICR2				0x008		*/
+#define LPC_LRST					(1 << 6)
+#define LPC_SDWN					(1 << 5)
+#define LPC_ABRT					(1 << 4)
+#define LPC_IBFIF3					(1 << 3)
+#define LPC_IBFIF2					(1 << 2)
+#define LPC_IBFIF1					(1 << 1)
+#define LPC_EERIE					(1)
+
+
+
+
+
+
+
+/*	AST_LPC_HICR4				0x010		*/
+#define LPC_HICS_LADR12AS			(1 << 7)
+#define LPC_HICS_CLRINTLRSTR		(1 << 6)
+#define LPC_HICS_STSINTLRSTR		(1 << 5)
+#define LPC_HICS_ENINTLRSTR			(1 << 4)
+/* bit 3 reserved */
+#define LPC_HICS_KCSENBL			(1 << 2)
+/* bit 1 reserved */
+#define LPC_HICS_BTENBL				(1)
+
+
+/*	AST_LPC_STR1				0: 0x03C, 1: 0x40, 2 : 0x44, 3: 4:		*/
+#define LPC_STR_DBU4				(1 << 7)		
+#define LPC_STR_DBU3				(1 << 6)
+#define LPC_STR_DBU2				(1 << 5)
+#define LPC_STR_DBU1				(1 << 4)
+#define LPC_STR_CMD_DAT				(1 << 3)
+#define LPC_STR_DBU0				(1 << 2)
+#define LPC_STR_IBF					(1 << 1)
+#define LPC_STR_OBF					(1)
+
+
+/* AST_LPC_HICR5				0x080	- LPC Host interface Control Register */
+#define LPC_HICR5_SNP1INT_EN		(1 << 3)
+#define LPC_HICR5_SNP1W_EN			(1 << 2)
+#define LPC_HICR5_SNP0INT_EN		(1 << 1)
+#define LPC_HICR5_SNP0W_EN			(1)
+
+/* AST_LPC_HICR6				0x084	- LPC Host Interface Control Register 6 */
+#define LPC_HICR6_STR_BAUD			(1 << 3)
+#define LPC_HICR6_STR_PME			(1 << 2)
+#define LPC_HICR6_STR_SNP1W			(1 << 1)
+#define LPC_HICR6_STR_SNP0W			(1)
+
+/* AST_LPC_SNPWADR				0x090	- LPC Snoop Address Register*/
+#define LPC_SNOOP_ADDR1_MASK		(0xffff << 16)
+#define LPC_SNOOP_ADDR0_MASK		(0xffff)
+
+/* AST_LPC_SNPWDR				0x094	- LPC SNoop Data Register */
+#define GET_LPC_SNPD1(x)			((x >> 7) & 0xff)
+#define GET_LPC_SNPD0(x)			(x & 0xff)
+
+/*AST_LPC_PCCR0				0x130	- Post Code Contol Register 0 */
+#define LPC_POST_DMA_INT_EN			(1 << 31)
+#define LPC_POST_DMA_MODE_EN		(1 << 14)
+#define LPC_RX_FIFO_CLR				(1 << 7)
+#define LPC_POST_
+#define LPC_POST_CODE_MODE_MASK		(0x3 << 4)
+#define LPC_POST_CODE_MODE(x)		(x << 4)
+#define BYTE_MODE	0
+#define WORD_MODE	1
+#define DWORD_MODE	2
+#define FULL_MODE	3
+
+#define LPC_POST_CODE_RXOVR			(1 << 3)
+#define LPC_POST_CODE_RXTO			(1 << 2)
+#define LPC_POST_CODE_RXAVA			(1 << 1)
+#define LPC_POST_CODE_EN			(1)
+
+/*AST_LPC_PCCR1				0x134	Post Code Contol Register 1 */
+#define LPC_POST_ADDR_MASK		0x3fffff
+#define LPC_CAPTURE_ADDR_MASK(x)	(x << 16)
+#define LPC_CAPTURE_BASE_ADDR(x)	(x)
+
+/*AST_LPC_PCCR2				0x138	Post Code Contol Register 2 */
+#define LPC_POST_CODE_DMA_RDY		(1 << 4)
+#define LPC_POST_CODE_STS			(1)
+
+#endif 
diff --git a/arch/arm/plat-aspeed/include/plat/regs-mbx.h b/arch/arm/plat-aspeed/include/plat/regs-mbx.h
new file mode 100644
index 0000000..636207f
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-mbx.h
@@ -0,0 +1,48 @@
+/* arch/arm/plat-aspeed/include/mach/regs-lpc.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED LPC Controller
+*/
+
+#ifndef __AST_MBX_H_
+#define __AST_MBX_H_
+
+#define AST_MBX_DAT0				0x00
+#define AST_MBX_DAT1				0x04
+#define AST_MBX_DAT2				0x08
+#define AST_MBX_DAT3				0x0C
+#define AST_MBX_DAT4				0x10
+#define AST_MBX_DAT5				0x14
+#define AST_MBX_DAT6				0x18
+#define AST_MBX_DAT7				0x1C
+#define AST_MBX_DAT8				0x20
+#define AST_MBX_DAT9				0x24
+#define AST_MBX_DATA				0x28
+#define AST_MBX_DATB				0x2C
+#define AST_MBX_DATC				0x30
+#define AST_MBX_DATD				0x34
+#define AST_MBX_DATE				0x38
+#define AST_MBX_DATF				0x3C
+#define AST_MBX_STS0				0x40
+#define AST_MBX_STS1				0x44
+#define AST_MBX_BCR					0x48
+#define AST_MBX_HCR					0x4C
+#define AST_MBX_BIE0				0x50
+#define AST_MBX_BIE1				0x54
+#define AST_MBX_HIE0				0x58
+#define AST_MBX_HIE1				0x5C
+
+/* AST_MBX_BCR					0x48 	*/
+#define	MBHIST			(1 << 7)
+#define	MBHMK			(1 << 1)
+#define	MBBINT			(1)
+
+
+
+#endif 
diff --git a/arch/arm/plat-aspeed/include/plat/regs-mctp.h b/arch/arm/plat-aspeed/include/plat/regs-mctp.h
new file mode 100644
index 0000000..2237cfe
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-mctp.h
@@ -0,0 +1,47 @@
+/* arch/arm/mach-aspeed/include/mach/regs-ast1010-scu.h
+ *
+ * Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *   History      : 
+ *    1. 2012/12/29 Ryan Chen Create
+ * 
+********************************************************************************/
+#ifndef __AST_MCTP_H
+#define __AST_MCTP_H                     1
+
+/*
+ *  Register for MCTP 
+ *  */
+#define AST_MCTP_CTRL			0x00		/*	Engine Status and Engine Control	*/
+#define AST_MCTP_INT			0x04		/*	Interrupt Enable and Status Register */
+#define AST_MCTP_ID				0x08		/*	Target ID and Mask */
+#define AST_MCTP_TX_DESC3		0x10		/*	Sending Descriptor [127:96] */
+#define AST_MCTP_TX_DESC2		0x14		/*	Sending Descriptor [95:64] */
+#define AST_MCTP_TX_DESC1		0x18		/*	Sending Descriptor [63:32] */
+#define AST_MCTP_TX_DESC0		0x1C		/*	Sending Descriptor [31:0] */
+#define AST_MCTP_TX_DATA		0x20		/*	Sending Data Port */
+#define AST_MCTP_RX_DESC3		0x40		/*	Received Descriptor [127:96] */
+#define AST_MCTP_RX_DESC2		0x44		/*	Received Descriptor [95:64] */
+#define AST_MCTP_RX_DESC1		0x48		/*	Received Descriptor [63:32] */
+#define AST_MCTP_RX_DESC0		0x4C		/*	Received Descriptor [31:0] */
+#define AST_MCTP_RX_DATA		0x50		/*	Received Data Port */
+
+#define AST_MCTP_DEC_ADDR		0x80		/*	ADDR */
+#define AST_MCTP_DEC_MASK		0x84		/*	MASK */
+#define AST_MCTP_DEC_TAG		0x88		/*	TAG */
+
+/*	AST_MCTP_CTRL			0x00		Engine Status and Engine Control	*/
+
+/*	AST_MCTP_INT			0x04		Interrupt Enable and Status Register */
+#define MCTP_RX_INT_EN			(1 << 17)
+#define MCTP_TX_INT_EN			(1 << 16)
+
+#define MCTP_RX_COMPLETE		(1 << 1)
+#define MCTP_TX_COMPLETE		(1)
+
+#endif
+
diff --git a/arch/arm/plat-aspeed/include/plat/regs-pcie.h b/arch/arm/plat-aspeed/include/plat/regs-pcie.h
new file mode 100644
index 0000000..bd699fc
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-pcie.h
@@ -0,0 +1,68 @@
+/* arch/arm/mach-aspeed/include/mach/regs-ast1010-scu.h
+ *
+ * Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *   History      : 
+ *    1. 2012/12/29 Ryan Chen Create
+ * 
+********************************************************************************/
+#ifndef __AST_PCIE_H
+#define __AST_PCIE_H                     1
+
+/*
+ *  Register for PCIE 
+ *  */
+#define AST_PCIE_CFG2			0x04
+#define AST_PCIE_SSID			0x28
+#define AST_PCIE_GLOBAL			0x30
+#define AST_PCIE_LOCK			0x7C
+
+#define AST_PCIE_LINK			0xC0
+#define AST_PCIE_INT			0xC4
+
+/* 	AST_PCIE_CFG2			0x04		*/
+#define PCIE_CFG_CLASS_CODE(x)	(x << 8)
+#define PCIE_CFG_REV_ID(x)		(x)
+
+
+/*SSID: 1E6ED028h[19:4]*/
+/*SSVID: 1E6ED028h[3:0], 1E6ED024h[31:20]*/
+
+/* AST_PCIE_SSID_A			0x24		*/
+/* 31:20 */
+#define PCIE_SSVID_H(x)			(x)
+
+/* AST_PCIE_SSID_B			0x28		*/
+/* 19:14 */
+#define PCIE_SSID(x)			(x << 4)
+/* 3:0 */
+#define PCIE_SSVID_L(x)			(x)
+
+
+/* 	AST_PCIE_GLOBAL			0x30 	*/
+#define ROOT_COMPLEX_ID(x)		(x << 4)
+
+
+/* 	AST_PCIE_LOCK			0x7C	*/
+#define PCIE_UNLOCK				0xa8
+
+/*	AST_PCIE_LINK			0xC0	*/
+#define PCIE_LINK_STS			(1 << 5)
+
+/*	AST_PCIE_INT			0xC4	*/
+#define PCIE_INTD				(1 << 16)
+#define PCIE_INTC				(1 << 15)
+#define PCIE_INTB				(1 << 14)
+#define PCIE_INTA				(1 << 13)
+
+#define AST_PCIE_NONP_MEM_BASE		AST_PCIE0_WIN_BASE0
+#define AST_PCIE_NONP_MEM_SIZE		AST_PCIE0_WIN_SIZE0
+#define AST_PCIE_PREF_MEM_BASE		0x0
+#define AST_PCIE_PREF_MEM_SIZE		0x0
+
+#endif
+
diff --git a/arch/arm/plat-aspeed/include/plat/regs-peci.h b/arch/arm/plat-aspeed/include/plat/regs-peci.h
new file mode 100644
index 0000000..266daca
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-peci.h
@@ -0,0 +1,106 @@
+/* arch/arm/plat-aspeed/include/mach/regs-peci.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED PECI Controller
+*/
+
+#ifndef __ASM_ARCH_REGS_PECI_H
+#define __ASM_ARCH_REGS_PECI_H __FILE__
+
+/*AST PECI Register Definition */
+#define AST_PECI_CTRL		0x00
+#define AST_PECI_TIMING 	0x04
+#define AST_PECI_CMD		0x08
+#define AST_PECI_CMD_CTRL	0x0C
+#define AST_PECI_EXP_FCS	0x10
+#define AST_PECI_CAP_FCS	0x14
+#define AST_PECI_INT_CTRL	0x18
+#define AST_PECI_INT_STS	0x1C
+#define AST_PECI_W_DATA0	0x20
+#define AST_PECI_W_DATA1	0x24
+#define AST_PECI_W_DATA2	0x28
+#define AST_PECI_W_DATA3	0x2c
+#define AST_PECI_R_DATA0	0x30
+#define AST_PECI_R_DATA1	0x34
+#define AST_PECI_R_DATA2	0x38
+#define AST_PECI_R_DATA3	0x3c
+#define AST_PECI_W_DATA4	0x40
+#define AST_PECI_W_DATA5	0x44
+#define AST_PECI_W_DATA6	0x48
+#define AST_PECI_W_DATA7	0x4c
+#define AST_PECI_R_DATA4	0x50
+#define AST_PECI_R_DATA5	0x54
+#define AST_PECI_R_DATA6	0x58
+#define AST_PECI_R_DATA7	0x5c
+
+
+/* AST_PECI_CTRL - 0x00 : Control Register */
+#define PECI_CTRL_SAMPLING_MASK			(0xf << 16)
+#define PECI_CTRL_SAMPLING(x)			(x << 16)
+#define PECI_CTRL_READ_MODE_MASK		(0xf << 12)
+#define PECI_CTRL_CONT_MODE				(1 << 16)
+#define PECI_CTRL_DBG_MODE				(2 << 16)
+#define PECI_CTRL_CLK_SOURCE			(0x1 << 11)	//0: 24Mhz, 1: MCLK
+#define PECI_CTRL_CLK_DIV_MASK			(0x3 << 8)	
+#define PECI_CTRL_CLK_DIV(x)			(x << 8)	
+#define PECI_CTRL_INVERT_OUT			(0x1 << 7)	
+#define PECI_CTRL_INVERT_IN				(0x1 << 6)	
+#define PECI_CTRL_BUS_CONTENT_EN		(0x1 << 5)	
+#define PECI_CTRL_PECI_EN				(0x1 << 4)	
+#define PECI_CTRL_PECI_CLK_EN			(0x1)	
+
+/* AST_PECI_TIMING - 0x04 : Timing Negotiation */
+#define PECI_TIMING_MESSAGE_GET(x)		((x & 0xff00) >> 8)
+#define PECI_TIMING_MESSAGE(x)			(x << 8)
+#define PECI_TIMING_ADDRESS_GET(x)		(x & 0xff)
+#define PECI_TIMING_ADDRESS(x)			(x)
+
+/* AST_PECI_CMD	- 0x08 : Command Register */
+#define PECI_CMD_PIN_MON				(0x1 << 31)
+#define PECI_CMD_STS					(0xf << 24)
+#define PECI_CMD_FIRE					(0x1)
+
+/* AST_PECI_LEN	- 0x0C : Read/Write Length Register */
+#define PECI_AW_FCS_EN					(0x1 << 31)
+#define PECI_READ_LEN_MASK				(0xff << 16)
+#define PECI_READ_LEN(x)				(x << 16)
+#define PECI_WRITE_LEN_MASK				(0xff << 8)
+#define PECI_WRITE_LEN(x)				(x << 8)
+#define PECI_TAGET_ADDR_MASK			(0xff)
+#define PECI_TAGET_ADDR(x)				(x)
+
+
+/* AST_PECI_EXP_FCS	- 0x10 : Expected FCS Data Register  */
+#define PECI_PROGRAM_AW_FCS				(0xf << 24) 
+#define PECI_EXPECT_READ_FCS			(0xf << 16) 
+#define PECI_EXPECT_AW_FCS_AUTO			(0xf << 8) 
+#define PECI_EXPECT_WRITE_FCS			(0xf) 
+
+/* AST_PECI_CAP_FCS	- 0x14 : Captured FCS Data Register */
+#define PECI_CAPTURE_READ_FCS(x)		((x & 0xff) >> 16) 
+#define PECI_CAPTURE_WRITE_FCS			(0xff) 
+
+/* AST_PECI_INT_CTRL/ STS  - 0x18/0x1c  : Interrupt Register */
+#define PECI_INT_TIMING_RESULT_MASK		(0x3 << 30)
+#define PECI_INT_TIMEOUT				(0x1 << 4)
+#define PECI_INT_CONNECT				(0x1 << 3)
+#define PECI_INT_W_FCS_BAD				(0x1 << 2)
+#define PECI_INT_W_FCS_ABORT			(0x1 << 1)
+#define PECI_INT_CMD_DONE				(0x1)
+
+#define    AUTO_GEN_AWFCS                         1
+//#define    ENABLE_BUS_CONTENTION                  0x20
+
+#define    DISABLE_ENGINE                         0
+#define    ENABLE_RX_ENGINE                       (1 << 0)
+#define    ENABLE_TX_ENGINE                       (1 << 1)
+#define    LEFT_CHANNEL_HIGH                      (1 << 16)
+#define    DELAY_CLOCK_CYCLE                      (1 << 17)
+
+#endif /* __ASM_ARCH_REGS_PECI_H */
diff --git a/arch/arm/plat-aspeed/include/plat/regs-pwm_fan.h b/arch/arm/plat-aspeed/include/plat/regs-pwm_fan.h
new file mode 100644
index 0000000..23d5b77
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-pwm_fan.h
@@ -0,0 +1,250 @@
+/* arch/arm/plat-aspeed/include/mach/regs-pwm-fan.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED PWM & Fan Tacho Controller
+*/
+
+#ifndef __ASM_ARCH_REGS_PWM_FAN_H
+#define __ASM_ARCH_REGS_PWM_FAN_H __FILE__
+
+/*AST PWM & FAN Register Definition */
+#define AST_PTCR_CTRL			0x00
+#define AST_PTCR_CLK_CTRL		0x04
+#define AST_PTCR_DUTY0_CTRL		0x08
+#define AST_PTCR_DUTY1_CTRL		0x0c
+#define AST_PTCR_TYPEM_CTRL0	0x10
+#define AST_PTCR_TYPEM_CTRL1	0x14
+#define AST_PTCR_TYPEN_CTRL0	0x18
+#define AST_PTCR_TYPEN_CTRL1	0x1c
+#define AST_PTCR_TACH_SOURCE	0x20
+// no 0x24
+#define AST_PTCR_TRIGGER		0x28
+#define AST_PTCR_RESULT			0x2c
+#define AST_PTCR_INTR_CTRL		0x30
+#define AST_PTCR_INTR_STS		0x34
+#define AST_PTCR_TYPEM_LIMIT	0x38
+#define AST_PTCR_TYPEN_LIMIT	0x3C
+#define AST_PTCR_CTRL_EXT		0x40
+#define AST_PTCR_CLK_EXT_CTRL	0x44
+#define AST_PTCR_DUTY2_CTRL		0x48
+#define AST_PTCR_DUTY3_CTRL		0x4c
+#define AST_PTCR_TYPEO_CTRL0	0x50
+#define AST_PTCR_TYPEO_CTRL1	0x54
+#define AST_PTCR_TACH_SOURCE_EXT 0x60
+#define AST_PTCR_TYPEO_LIMIT	0x78
+
+//COMMON Definition 
+#define FALL_EDGE					(0)
+#define RISE_EDGE					(0x1)
+#define BOTH_EDGE					(0x2)
+
+#ifdef CONFIG_ARCH_AST1010
+#define PWM_TYPE_NUM		2
+#define PWM_TYPE_M			0x0
+#define PWM_TYPE_N			0x1
+#define PWM_TYPE_MASK		0x1
+#else
+#define PWM_TYPE_NUM		3
+#define PWM_TYPE_M			0x0
+#define PWM_TYPE_N			0x1
+#define PWM_TYPE_O			0x2
+#define PWM_TYPE_MASK		0x3
+
+#endif
+
+#define TACHO_NUM	16
+#define PWM_CH_NUM	8
+#define PWMA	0x0
+#define PWMB	0x1
+#define PWMC	0x2
+#define PWMD	0x3
+#define PWME	0x4
+#define PWMF	0x5
+#define PWMG	0x6
+#define PWMH	0x7
+
+
+// AST_PTCR_CTRL:0x00 - PWM-FAN General Control Register 
+#define AST_PTCR_CTRL_SET_PWMD_TYPE(x)		((x&0x1)<<15 | (x&0x2) <<6)
+#define AST_PTCR_CTRL_GET_PWMD_TYPE(x)		(((x&(0x1<<7))>>6) | ((x&(0x1<<15))>>15))
+#define AST_PTCR_CTRL_SET_PWMD_TYPE_MASK	((0x1<<7) | (0x1<<15))
+
+#define AST_PTCR_CTRL_SET_PWMC_TYPE(x)		((x&0x1)<<14 | (x&0x2) <<5)
+#define AST_PTCR_CTRL_GET_PWMC_TYPE(x)		(((x&(0x1<<6))>>5) | ((x&(0x1<<14))>>14))
+#define AST_PTCR_CTRL_SET_PWMC_TYPE_MASK	((0x1<<6) | (0x1<<14))
+
+#define AST_PTCR_CTRL_SET_PWMB_TYPE(x)		((x&0x1)<<13 | (x&0x2) <<4)
+#define AST_PTCR_CTRL_GET_PWMB_TYPE(x)		(((x&(0x1<<5))>>4) | ((x&(0x1<<13))>>13))
+#define AST_PTCR_CTRL_SET_PWMB_TYPE_MASK	((0x1<<5) | (0x1<<13))
+
+
+#define AST_PTCR_CTRL_SET_PWMA_TYPE(x)		((x&0x1)<<12 | (x&0x2) <<3)
+#define AST_PTCR_CTRL_GET_PWMA_TYPE(x)		(((x&(0x1<<4))>>3) | ((x&(0x1<<12))>>12))
+#define AST_PTCR_CTRL_SET_PWMA_TYPE_MASK	((0x1<<4) | (0x1<<12))
+
+#define	AST_PTCR_CTRL_FAN_NUM_EN(x)		(0x1 << (16+x))
+
+#define	AST_PTCR_CTRL_PMWD			(11)
+#define	AST_PTCR_CTRL_PMWD_EN		(0x1 << 11)
+#define	AST_PTCR_CTRL_PMWC			(10)
+#define	AST_PTCR_CTRL_PMWC_EN		(0x1 << 10)
+#define	AST_PTCR_CTRL_PMWB			(9)
+#define	AST_PTCR_CTRL_PMWB_EN		(0x1 << 9)
+#define	AST_PTCR_CTRL_PMWA			(8)
+#define	AST_PTCR_CTRL_PMWA_EN		(0x1 << 8)
+
+#define	AST_PTCR_CTRL_CLK_MCLK		0x2		//0:24Mhz, 1:MCLK
+#define	AST_PTCR_CTRL_CLK_EN		0x1
+
+// AST_PTCR_CLK_CTRL:0x04 - PWM-FAN Clock Control Register
+//TYPE N
+#define AST_PTCR_CLK_CTRL_TYPEN_UNIT				(24)
+#define AST_PTCR_CLK_CTRL_TYPEN_UNIT_MASK			(0xff<<24)
+#define AST_PTCR_CLK_CTRL_TYPEN_H					(20)
+#define AST_PTCR_CLK_CTRL_TYPEN_H_MASK				(0xf<<20)
+#define AST_PTCR_CLK_CTRL_TYPEN_L					(16)
+#define AST_PTCR_CLK_CTRL_TYPEN_L_MASK				(0xf<<16)
+//TYPE M
+#define AST_PTCR_CLK_CTRL_TYPEM_UNIT				(8)
+#define AST_PTCR_CLK_CTRL_TYPEM_UNIT_MASK			(0xff<<8)
+#define AST_PTCR_CLK_CTRL_TYPEM_H					(4)
+#define AST_PTCR_CLK_CTRL_TYPEM_H_MASK				(0xf<<4)
+#define AST_PTCR_CLK_CTRL_TYPEM_L					(0)
+#define AST_PTCR_CLK_CTRL_TYPEM_L_MASK				(0xf)
+
+
+// AST_PTCR_DUTY_CTRL0:0x08 - PWM-FAN duty control 0 register
+#define DUTY_CTRL0_PWMB_FALL_POINT					(24)
+#define DUTY_CTRL0_PWMB_FALL_POINT_MASK				(0xff<<24)
+#define DUTY_CTRL0_PWMB_RISE_POINT					(16)
+#define DUTY_CTRL0_PWMB_RISE_POINT_MASK				(0xff<<16)
+#define DUTY_CTRL0_PWMA_FALL_POINT					(8)
+#define DUTY_CTRL0_PWMA_FALL_POINT_MASK				(0xff<<8)
+#define DUTY_CTRL0_PWMA_RISE_POINT					(0)
+#define DUTY_CTRL0_PWMA_RISE_POINT_MASK				(0xff)
+
+
+// AST_PTCR_DUTY_CTRL1 : 0x0c - PWM-FAN duty control 1 register
+#define DUTY_CTRL1_PWMD_FALL_POINT					(24)
+#define DUTY_CTRL1_PWMD_FALL_POINT_MASK				(0xff<<24)
+#define DUTY_CTRL1_PWMD_RISE_POINT					(16)
+#define DUTY_CTRL1_PWMD_RISE_POINT_MASK				(0xff<<16)
+#define DUTY_CTRL1_PWMC_FALL_POINT					(8)
+#define DUTY_CTRL1_PWMC_FALL_POINT_MASK				(0xff<<8)
+#define DUTY_CTRL1_PWMC_RISE_POINT					(0)
+#define DUTY_CTRL1_PWMC_RISE_POINT_MASK				(0xff)
+
+
+// AST_PTCR_TYPEM_CTRL0 : 0x10/0x18/0x50 - Type M/N/O Ctrl 0 Register
+#define TYPE_CTRL0_FAN_PERIOD						(16)
+#define TYPE_CTRL0_FAN_PERIOD_MASK					(0xffff<<16)
+//Type O not have this
+#define TYPE_CTRL0_FLAT_EN							(0x1<<7)
+
+
+// 0 : FALL_EDGE,	0x1 : RISE_EDGE , 0x2 :BOTH_EDGE	
+#define TYPE_CTRL0_FAN_MODE							(4)
+#define TYPE_CTRL0_FAN_MODE_MASK					(0x3<<4)
+
+
+
+#define TYPE_CTRL0_CLK_DIVISION						(1)
+#define TYPE_CTRL0_CLK_DIVISION_MASK				(0x7<<1)
+
+#define TYPE_CTRL0_FAN_TYPE_EN							(1)
+
+
+// AST_PTCR_TYPEM_CTRL1 : 0x14/0x1c/0x54 - Type M/N/O Ctrl 1 Register
+#define TYPE_CTRL1_FALL_POINT						(16)
+#define TYPE_CTRL1_FALL_POINT_MASK					(0xff<<16)
+#define TYPE_CTRL1_RISE_POINT						(0)
+#define TYPE_CTRL1_RISE_POINT_MASK					(0xff)
+
+
+// AST_PTCR_TACH_SOURCE : 0x20/0x60 - Tach Source Register
+//bit [0,1] at 0x20, bit [2] at 0x60
+#define TACH_PWM_SOURCE_BIT01(x)					(x*2)
+#define TACH_PWM_SOURCE_BIT2(x)						(x*2)
+
+#define TACH_PWM_SOURCE_MASK_BIT01(x)						(0x3<<(x*2))
+#define TACH_PWM_SOURCE_MASK_BIT2(x)						(0x1<<(x*2))
+
+// AST_PTCR_TRIGGER : 0x28 - Trigger Register
+#define TRIGGER_READ_FAN_NUM(x)						(0x1<<x)
+
+// AST_PTCR_RESULT : 0x2c - Result Register
+#define RESULT_STATUS								(31)
+
+#define RESULT_VALUE_MASK							(0xfffff)
+
+// AST_PTCR_INTR_CTRL : 0x30 - Interrupt Ctrl Register
+#define INTR_CTRL_EN_NUM(x)							(0x1<<x)
+
+// AST_PTCR_INTR_STS : 0x34 - Interrupt Status Register		
+#define INTR_CTRL_NUM(x)							(0x1<<x)
+
+//AST_PTCR_TYPEM_LIMIT, AST_PTCR_TYPEN_LIMIT,AST_PTCR_TYPEO_LIMIT  : 0x38/0x3C/0x78 - Type M / N / O Limit Register		
+#define FAN_LIMIT_MASK								(0xfffff)
+
+// AST_PTCR_CTRL_EXT : 0x40 - General Ctrl Extension #1
+#define AST_PTCR_CTRL_SET_PWMH_TYPE(x)		((x&0x1)<<15 | (x&0x2) <<6)
+#define AST_PTCR_CTRL_GET_PWMH_TYPE(x)		(((x&(0x1<<7))>>6) | ((x&(0x1<<15))>>15))
+#define AST_PTCR_CTRL_SET_PWMH_TYPE_MASK	((0x1<<7) | (0x1<<15))
+
+#define AST_PTCR_CTRL_SET_PWMG_TYPE(x)		((x&0x1)<<14 | (x&0x2) <<5)
+#define AST_PTCR_CTRL_GET_PWMG_TYPE(x)		(((x&(0x1<<6))>>5) | ((x&(0x1<<14))>>14))
+#define AST_PTCR_CTRL_SET_PWMG_TYPE_MASK	((0x1<<6) | (0x1<<14))
+
+#define AST_PTCR_CTRL_SET_PWMF_TYPE(x)		((x&0x1)<<13 | (x&0x2) <<4)
+#define AST_PTCR_CTRL_GET_PWMF_TYPE(x)		(((x&(0x1<<5))>>4) | ((x&(0x1<<13))>>13))
+#define AST_PTCR_CTRL_SET_PWMF_TYPE_MASK	((0x1<<5) | (0x1<<13))
+
+#define AST_PTCR_CTRL_SET_PWME_TYPE(x)		((x&0x1)<<12 | (x&0x2) <<3)
+#define AST_PTCR_CTRL_GET_PWME_TYPE(x)		(((x&(0x1<<4))>>3) | ((x&(0x1<<12))>>12))
+#define AST_PTCR_CTRL_SET_PWME_TYPE_MASK	((0x1<<4) | (0x1<<12))
+
+#define	AST_PTCR_CTRL_PMWH			(11)
+#define	AST_PTCR_CTRL_PMWH_EN		(0x1 << 11)
+#define	AST_PTCR_CTRL_PMWG			(10)
+#define	AST_PTCR_CTRL_PMWG_EN		(0x1 << 10)
+#define	AST_PTCR_CTRL_PMWF			(9)
+#define	AST_PTCR_CTRL_PMWF_EN		(0x1 << 9)
+#define	AST_PTCR_CTRL_PMWE			(8)
+#define	AST_PTCR_CTRL_PMWE_EN		(0x1 << 8)
+
+// AST_PTCR_CLK_EXT_CTRL : 0x44 - Clock Control Extension #1 
+//TYPE O
+#define AST_PTCR_CLK_CTRL_TYPEO_UNIT				(8)
+#define AST_PTCR_CLK_CTRL_TYPEO_UNIT_MASK			(0xff<<8)
+#define AST_PTCR_CLK_CTRL_TYPEO_H					(4)
+#define AST_PTCR_CLK_CTRL_TYPEO_H_MASK				(0xf<<4)
+#define AST_PTCR_CLK_CTRL_TYPEO_L					(0)
+#define AST_PTCR_CLK_CTRL_TYPEO_L_MASK				(0xf)
+
+// AST_PTCR_DUTY2_CTRL : 0x48 - Duty Control 2 Register
+#define DUTY_CTRL2_PWMF_FALL_POINT					(24)
+#define DUTY_CTRL2_PWMF_FALL_POINT_MASK				(0xff<<24)
+#define DUTY_CTRL2_PWMF_RISE_POINT					(16)
+#define DUTY_CTRL2_PWMF_RISE_POINT_MASK				(0xff<<16)
+#define DUTY_CTRL2_PWME_FALL_POINT					(8)
+#define DUTY_CTRL2_PWME_FALL_POINT_MASK				(0xff<<8)
+#define DUTY_CTRL2_PWME_RISE_POINT					(0)
+#define DUTY_CTRL2_PWME_RISE_POINT_MASK				(0xff)
+
+// AST_PTCR_DUTY3_CTRL : 0x4c - Duty Control 3 Register
+#define DUTY_CTRL3_PWMH_FALL_POINT					(24)
+#define DUTY_CTRL3_PWMH_FALL_POINT_MASK				(0xff<<24)
+#define DUTY_CTRL3_PWMH_RISE_POINT					(16)
+#define DUTY_CTRL3_PWMH_RISE_POINT_MASK				(0xff<<16)
+#define DUTY_CTRL3_PWMG_FALL_POINT					(8)
+#define DUTY_CTRL3_PWMG_FALL_POINT_MASK				(0xff<<8)
+#define DUTY_CTRL3_PWMG_RISE_POINT					(0)
+#define DUTY_CTRL3_PWMG_RISE_POINT_MASK				(0xff)
+
+#endif /* __ASM_ARCH_REGS_PWM_FAN_H */
diff --git a/arch/arm/plat-aspeed/include/plat/regs-rtc.h b/arch/arm/plat-aspeed/include/plat/regs-rtc.h
new file mode 100644
index 0000000..8a09a4b
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-rtc.h
@@ -0,0 +1,64 @@
+/* arch/arm/plat-aspeed/include/mach/regs-iic.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED I2C Controller
+*/
+
+#ifndef __ASM_ARCH_REGS_RTC_H
+#define __ASM_ARCH_REGS_RTC_H __FILE__
+
+#define RTC_CNTR_STS_1			0x00
+#define RTC_CNTR_STS_2			0x04
+#define RTC_ALARM				0x08
+#define RTC_CONTROL				0x10
+#define RTC_ALARM_STS			0x14
+
+/* RTC_CNTR_STS_1			0x00 */
+/* RTC_ALARM				0x08 */
+#define GET_DAY_VAL(x)	((x >> 24)&0x1f)
+#define GET_HOUR_VAL(x)	((x >> 16)&0x1f)
+#define GET_MIN_VAL(x)	((x >> 8)&0x3f)
+#define GET_SEC_VAL(x)	(x & 0x3f)
+
+#define SET_DAY_VAL(x)	((x&0x1f) << 24)
+#define SET_HOUR_VAL(x)	((x&0x1f) << 16)
+#define SET_MIN_VAL(x)	((x&0x3f) << 8)
+#define SET_SEC_VAL(x)	(x & 0x3f)
+
+/* RTC_CNTR_STS_2			0x04 */
+#define GET_CENT_VAL(x)	((x >> 16)&0x1f)
+#define GET_YEAR_VAL(x)	((x >> 8)&0x7f)
+#define GET_MON_VAL(x)	(x & 0xf)
+
+#define SET_CENT_VAL(x)	((x &0x1f) << 16)
+#define SET_YEAR_VAL(x)	((x &0x7f) << 8)
+#define SET_MON_VAL(x)	(x & 0xf)
+
+/* RTC_CONTROL				0x10 */
+#define ENABLE_SEC_INTERRUPT	(1 << 7)
+#define ENABLE_DAY_ALARM		(1 << 6)
+#define ENABLE_HOUR_ALARM		(1 << 5)
+#define ENABLE_MIN_ALARM		(1 << 4)
+#define ENABLE_SEC_ALARM		(1 << 3)
+#define ALARM_MODE_SELECT		(1 << 2)
+#define RTC_LOCK				(1 << 1)
+#define RTC_ENABLE				(1 << 0)
+#define ENABLE_ALL_ALARM		0x0000007c
+
+
+/* RTC_ALARM_STS			0x14 */
+#define SEC_INTERRUPT_STATUS	(1 << 4)
+#define DAY_ALARM_STATUS		(1 << 3)
+#define HOUR_ALARM_STATUS		(1 << 2)
+#define MIN_ALARM_STATUS		(1 << 1)
+#define SEC_ALARM_STATUS		(1 << 0)
+
+
+
+#endif /* __ASM_ARCH_REGS_RTC_H */
diff --git a/arch/arm/plat-aspeed/include/plat/regs-scu-g5.h b/arch/arm/plat-aspeed/include/plat/regs-scu-g5.h
new file mode 100644
index 0000000..0720be5
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-scu-g5.h
@@ -0,0 +1,702 @@
+/* arch/arm/mach-aspeed/include/mach/regs-ast2300-scu.h
+ *
+ * Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *   History      : 
+ *    1. 2012/12/29 Ryan Chen Create
+ * 
+********************************************************************************/
+#ifndef __AST_SCU_G5_REGS_H
+#define __AST_SCU_G5_REGS_H                     1
+
+/*
+ *  Register for SCU
+ *  */
+#define AST_SCU_PROTECT		0x00		/*	protection key register	*/
+#define AST_SCU_RESET		0x04		/*	system reset control register */
+#define AST_SCU_CLK_SEL		0x08		/*	clock selection register	*/
+#define AST_SCU_CLK_STOP	0x0C		/*	clock stop control register	*/
+#define AST_SCU_COUNT_CTRL	0x10		/*	frequency counter control register	*/
+#define AST_SCU_INTR_CTRL	0x14		/*	Interrupt control and status register	*/
+#define AST_SCU_D1_PLL		0x18		/*	D1-PLL Parameter  register	*/
+#define AST_SCU_D2_PLL		0x1C		/*	D2-PLL Parameter  register	*/
+#define AST_SCU_M_PLL		0x20		/*	M-PLL Parameter register		*/
+#define AST_SCU_H_PLL		0x24		/*	H-PLL Parameter register		*/
+#define AST_SCU_FREQ_LIMIT	0x28		/*	frequency counter comparsion register */
+#define AST_SCU_MISC1_CTRL	0x2C		/*	Misc. Control register */
+#define AST_SCU_PCI_CONF1	0x30		/*	PCI configuration setting register#1 */
+#define AST_SCU_PCI_CONF2	0x34		/*	PCI configuration setting register#2 */
+#define AST_SCU_PCI_CONF3	0x38		/*	PCI configuration setting register#3 */
+#define AST_SCU_SYS_CTRL	0x3C		/*	System reset contrl/status register*/
+#define AST_SCU_SOC_SCRATCH0	0x40		/*	SOC scratch 0~31 register */
+#define AST_SCU_SOC_SCRATCH1	0x44		/*	SOC scratch 32~63 register */
+#define AST_SCU_VGA0		0x40		/*	VGA fuction handshake register */
+#define AST_SCU_VGA1		0x44		/*	VGA fuction handshake register */
+#define AST_SCU_MAC_CLK		0x48		/*	MAC interface clock delay setting register */
+#define AST_SCU_MISC2_CTRL	0x4C		/*	Misc. 2 Control register */
+#define AST_SCU_VGA_SCRATCH0	0x50		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH1	0x54		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH2	0x58		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH3	0x5c		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH4	0x60		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH5	0x64		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH6	0x68		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH7	0x6c		/*	VGA Scratch register */
+#define AST_SCU_HW_STRAP1			0x70		/*	hardware strapping register */
+#define AST_SCU_RAMDOM_GEN		0x74		/*	random number generator register */
+#if defined(CONFIG_ARCH_1100) || defined(CONFIG_ARCH_2050) || defined(CONFIG_ARCH_2100) || defined(CONFIG_ARCH_2200)
+#define AST_SCU_MULTI_FUNC_2	0x78
+#else
+#define AST_SCU_RAMDOM_DATA		0x78		/*	random number generator data output*/
+#endif
+#define AST_SCU_REVISION_ID		0x7C		/*	Silicon revision ID register */
+#define AST_SCU_FUN_PIN_CTRL1		0x80		/*	Multi-function Pin Control#1*/
+#define AST_SCU_FUN_PIN_CTRL2		0x84		/*	Multi-function Pin Control#2*/
+#define AST_SCU_FUN_PIN_CTRL3		0x88		/*	Multi-function Pin Control#3*/
+#define AST_SCU_FUN_PIN_CTRL4		0x8C		/*	Multi-function Pin Control#4*/
+#define AST_SCU_FUN_PIN_CTRL5		0x90		/*	Multi-function Pin Control#5*/
+#define AST_SCU_FUN_PIN_CTRL6		0x94		/*	Multi-function Pin Control#6*/
+#define AST_SCU_WDT_RESET		0x9C		/*	Watchdog Reset Selection */
+#define AST_SCU_FUN_PIN_CTRL7		0xA0		/*	Multi-function Pin Control#7*/
+#define AST_SCU_FUN_PIN_CTRL8		0xA4		/*	Multi-function Pin Control#8*/
+#define AST_SCU_FUN_PIN_CTRL9		0xA8		/*	Multi-function Pin Control#9*/
+#define AST_SCU_PWR_SAVING_EN		0xC0		/*	Power Saving Wakeup Enable*/
+#define AST_SCU_PWR_SAVING_CTRL		0xC4		/*	Power Saving Wakeup Control*/
+#define AST_SCU_HW_STRAP2			0xD0		/*	Haardware strapping register set 2*/
+#define AST_SCU_COUNTER4			0xE0		/*	SCU Free Run Counter Read Back #4*/
+#define AST_SCU_COUNTER4_EXT		0xE4		/*	SCU Free Run Counter Extended Read Back #4*/
+
+//CPU 2 
+#define AST_SCU_CPU2_CTRL			0x100		/*	CPU2 Control Register*/
+#define AST_SCU_CPU2_BASE0_ADDR		0x104		/*	CPU2 Base Address for Segment 0x00:0000~0x1F:FFFF*/
+#define AST_SCU_CPU2_BASE1_ADDR		0x108		/*	CPU2 Base Address for Segment 0x20:0000~0x3F:FFFF*/
+#define AST_SCU_CPU2_BASE2_ADDR		0x10C		/*	CPU2 Base Address for Segment 0x40:0000~0x5F:FFFF*/
+#define AST_SCU_CPU2_BASE3_ADDR		0x110		/*	CPU2 Base Address for Segment 0x60:0000~0x7F:FFFF*/
+#define AST_SCU_CPU2_BASE4_ADDR		0x114		/*	CPU2 Base Address for Segment 0x80:0000~0xFF:FFFF*/
+#define AST_SCU_CPU2_CACHE_CTRL		0x118		/*	CPU2 Cache Function Control */
+
+//
+#define AST_SCU_UART24_REF			0x160		/*	Generate UART 24Mhz Ref from H-PLL when CLKIN is 25Mhz */
+#define AST_SCU_PCIE_CONFIG_SET		0x180		/*	PCI-E Configuration Setting Control Register */
+#define AST_SCU_BMC_MMIO_DEC		0x184		/*	BMC MMIO Decode Setting Register */
+#define AST_SCU_DEC_AREA1			0x188		/*	1st relocated controller decode area location */
+#define AST_SCU_DEC_AREA2			0x18C		/*	2nd relocated controller decode area location */
+#define AST_SCU_MBOX_DEC_AREA		0x190		/*	Mailbox decode area location*/
+#define AST_SCU_SRAM_DEC_AREA0		0x194		/*	Shared SRAM area decode location*/
+#define AST_SCU_SRAM_DEC_AREA1		0x198		/*	Shared SRAM area decode location*/
+#define AST_SCU_BMC_CLASS			0x19C		/*	BMC device class code and revision ID */
+#define AST_SCU_BMC_DEV_ID			0x1A4		/*	BMC device ID */
+
+
+/*	AST_SCU_PROTECT: 0x00  - protection key register */
+#define SCU_PROTECT_UNLOCK			0x1688A8A8
+
+/*	AST_SCU_RESET :0x04	 - system reset control register */
+#define SCU_RESET_I2S				(0x1 << 31)
+#define SCU_RESET_IR				(0x1 << 30)
+#define SCU_RESET_PS21				(0x1 << 29)
+#define SCU_RESET_PS20				(0x1 << 28)
+#define SCU_PWAKE_PIN_EN			(0x1 << 27)
+#define SCU_PWAKE_PIN_OUT			(0x1 << 26
+#define SCU_RESET_X_DMA				(0x1 << 25)
+#define SCU_RESET_MCTP				(0x1 << 24)
+//#define SCU_RESET_ADC				(0x1 << 23) reserved 
+#define SCU_RESET_JTAG				(0x1 << 22)
+#define SCU_RESET_PCIE_EN			(0x1 << 21)
+#define SCU_RESET_PCIE_OUT			(0x1 << 20)
+#define SCU_RESET_PCIE				(0x1 << 19)
+#define SCU_RESET_H264				(0x1 << 18)
+#define SCU_RESET_RFX				(0x1 << 17)
+#define SCU_RESET_SD				(0x1 << 16)
+#define SCU_RESET_USB11				(0x1 << 15)
+#define SCU_RESET_USB20				(0x1 << 14)
+#define SCU_RESET_CRT				(0x1 << 13)
+//#define SCU_RESET_MAC1				(0x1 << 12) reserved
+#define SCU_RESET_MAC0				(0x1 << 11)
+//#define SCU_RESET_PECI				(0x1 << 10)
+//#define SCU_RESET_PWM				(0x1 << 9)
+#define SCU_PCI_VGA_DIS				(0x1 << 8)
+#define SCU_RESET_2D				(0x1 << 7)
+#define SCU_RESET_VIDEO				(0x1 << 6)
+//#define SCU_RESET_LPC				(0x1 << 5)
+#define SCU_RESET_HAC				(0x1 << 4)
+//#define SCU_RESET_USB11_HID			(0x1 << 3)
+#define SCU_RESET_I2C				(0x1 << 2)
+#define SCU_RESET_AHB				(0x1 << 1)
+#define SCU_RESET_SRAM_CTRL			(0x1 << 0)
+
+/*	AST_SCU_CLK_SEL	 : 0x08 - clock selection register	*/
+#define SCU_CLK_VIDEO_SLOW_EN		(0x1 << 31)
+#define SCU_CLK_VIDEO_SLOW_SET(x)	((x & 0x7) << 28)
+#define SCU_CLK_VIDEO_SLOW_MASK		(0x7 << 28)
+#define SCU_CLK_2D_ENG_GCLK_INVERT	(0x1 << 27)		//valid only at CRT mode SCU2C[7]
+#define SCU_CLK_2D_ENG_THROT_EN		(0x1 << 26)		//valid only at CRT mode SCU2C[7]
+#define SCU_PCLK_APB_DIV(x)			((x & 0x7) << 23)
+#define SCU_GET_PCLK_DIV(x)			((x >> 23) & 0x7)
+#define SCU_PCLK_APB_DIV_MASK		(0x7 << 23)		//limitation on PCLK .. PCLK > 0.5*LCLK (33Mhz)
+//#define SCU_GET_LHCLK_DIV(x)		((x >> 20) & 0x7)
+//#define SCU_SET_LHCLK_DIV(x)		(x << 20)
+//#define SCU_LHCLK_DIV_MASK			(0x7 << 20)
+//#define SCU_LHCLK_SOURCE_EN			(0x1 << 19)		//0: ext , 1:internel
+#define SCU_SET_MAC_DIV(x)			((x & 0x7) << 16)
+#define SCU_GET_MAC_DIV(x)			((x >> 16) & 0x7)
+#define SCU_CLK_MAC_MASK			(0x7 << 16)
+#define SCU_CLK_SD_EN				(0x1 << 15)
+#define SCU_SET_SD_DIV(x)			((x & 0x7) << 12)
+#define SCU_GET_SD_DIV(x)			((x >> 12) & 0x7)
+#define SCU_CLK_SD_MASK				(0x7 << 12)
+//
+#define SCU_CLK_VIDEO_DELAY(x)		((x & 0xf) << 8)
+#define SCU_CLK_VIDEO_DELAY_MASK	(0xf << 8)
+#define SCU_CLK_CPU_AHB_SLOW_EN		(0x1 << 7)
+#define SCU_CLK_CPU_AHB_SLOW(x)		((x & 0x7) << 4)
+#define SCU_CLK_CPU_AHB_SLOW_MASK	(0x7 << 4)
+#define SCU_GET_CPU_AHB_DIV(x)		((x >> 4) & 0x7)
+#define SCU_ECLK_SOURCE(x)			(x << 2)
+#define SCU_ECLK_SOURCE_MASK		(0x3 << 2)
+#define SCU_CLK_CPU_AHB_SLOW_IDLE	(0x1 << 1)
+#define SCU_CLK_CPU_AHB_DYN_SLOW_EN	(0x1 << 0)
+
+/*	AST_SCU_CLK_STOP : 0x0C - clock stop control register	*/
+//#define SCU_LHCLK_STOP_EN			(0x1 << 28)
+#define SCU_SDCLK_STOP_EN			(0x1 << 27)
+#define SCU_IRCLK_STOP_EN			(0x1 << 26)
+#define SCU_I2SCLK_STOP_EN			(0x1 << 25)
+#define SCU_RSACLK_STOP_EN			(0x1 << 24)
+#define SCU_H264CLK_STOP_EN			(0x1 << 23)
+//bit 22 must keep 1 
+//#define SCU_MAC1CLK_STOP_EN			(0x1 << 21)
+#define SCU_MAC0CLK_STOP_EN			(0x1 << 20)
+#define SCU_BBCLK_STOP_EN			(0x1 << 19)
+#define SCU_RFXCLK_STOP_EN			(0x1 << 18)
+#define SCU_UART0_CLK_STOP_EN		(0x1 << 17)
+#define SCU_UART2_CLK_STOP_EN		(0x1 << 16)
+#define SCU_UART1_CLK_STOP_EN		(0x1 << 15)
+#define SCU_USB20_CLK_EN			(0x1 << 14)
+#define SCU_YCLK_STOP_EN			(0x1 << 13)
+#define SCU_PS2CLK_STOP_EN			(0x1 << 12)
+//
+#define SCU_D1CLK_STOP_EN			(0x1 << 10)
+#define SCU_USB11CLK_STOP_EN		(0x1 << 9)
+#define SCU_D4CLK_STOP_EN			(0x1 << 8)
+#define SCU_D3CLK_STOP_EN			(0x1 << 7)
+#define SCU_REFCLK_STOP_EN			(0x1 << 6)
+#define SCU_D2CLK_STOP_EN			(0x1 << 5)
+#define SCU_SACLK_STOP_EN			(0x1 << 4)
+#define SCU_VCLK_STOP_EN			(0x1 << 3)
+#define SCU_MCLK_STOP_EN			(0x1 << 2)
+#define SCU_GCLK_STOP_EN			(0x1 << 1)
+#define SCU_ECLK_STOP_EN			(0x1 << 0)
+
+/* AST_SCU_COUNT_CTRL : 0x10 - frequency counter control register	*/
+#define SCU_FREQ_COMP_RESULT			(0x1 << 7) 
+#define SCU_FREQ_MEASU_FINISH			(0x1 << 6)
+#define SCU_FREQ_SOURCE_FOR_MEASU(x)	((x & 0xf) << 2)
+#define SCU_FREQ_SOURCE_FOR_MEASU_MASK	(0xf << 2)
+
+#define SCU_SOURCE_6M					0xf
+#define SCU_SOURCE_12M					0xe
+#define SCU_SOURCE_I2SM_CLK				0xd
+#define SCU_SOURCE_H_CLK				0xc
+#define SCU_SOURCE_B_CLK				0xb
+#define SCU_SOURCE_D2_PLL				0xa
+
+#define SCU_SOURCE_VIDEO_CLK			0x7
+#define SCU_SOURCE_LPC_CLK				0x6
+#define SCU_SOURCE_JITTER_CLK			0x5
+#define SCU_SOURCE_M_CLK				0x4
+#define SCU_SOURCE_XP_CLK				0x3
+#define SCU_SOURCE_D_PLL				0x2
+#define SCU_SOURCE_NAND					0x1
+#define SCU_SOURCE_DEL_CELL				0x0
+
+#define SCU_OSC_COUNT_EN				(0x1 << 1)
+#define SCU_RING_OSC_EN					(0x1 << 0)
+
+/*  AST_SCU_INTR_CTRL : 0x14 - Interrupt control and status register   */
+//#define INTR_LPC_H_L_RESET				(0x1 << 21)
+//#define INTR_LPC_L_H_RESET				(0x1 << 20)
+#define INTR_PCIE_H_L_RESET				(0x1 << 17)
+#define INTR_PCIE_L_H_RESET				(0x1 << 16)
+//#define INTR_VGA_SCRATCH_CHANGE			(0x1 << 17)
+//#define INTR_VGA_CURSOR_CHANGE			(0x1 << 16)
+#define INTR_MSI_EN						(0x1 << 2)
+//#define INTR_LPC_H_L_RESET_EN			(0x1 << 1)
+//#define INTR_LPC_L_H_RESET_EN			(0x1 << 0)
+#define INTR_PCIE_H_L_RESET_EN			(0x1 << 1)
+#define INTR_PCIE_L_H_RESET_EN			(0x1 << 0)
+//#define INTR_VGA_SCRATCH_CHANGE_EN		(0x1 << 1)
+//#define INTR_VGA_CURSOR_CHANGE_EN		(0x1 << 0)
+
+
+/*	AST_SCU_D1_PLL: 0x18 - D1-PLL Parameter  register */
+#define SCU_D1_PLL_SET_PD2(x)			((x & 0x7) << 19)
+#define SCU_D1_PLL_GET_PD2(x)			((x >> 19) & 0x7)
+#define SCU_D1_PLL_PD2_MASK				(0x7 << 19)
+#define SCU_D1_PLL_BYPASS_EN			(0x1 << 18)
+#define SCU_D1_PLL_OFF					(0x1 << 17)
+#define SCU_D1_PLL_SET_PD(x)			((x & 0x3) << 15)
+#define SCU_D1_PLL_GET_PD(x)			((x >> 15) & 0x3)
+#define SCU_D1_PLL_PD_MASK				(0x3 << 15)
+#define SCU_D1_PLL_SET_OD(x)			((x & 0x3) << 13)
+#define SCU_D1_PLL_GET_OD(x)			((x >> 13) & 0x3)
+#define SCU_D1_PLL_OD_MASK				(0x3 << 13)
+#define SCU_D1_PLL_SET_DENUM(x)			((x & 0x1f) << 8)
+#define SCU_D1_PLL_GET_DENUM(x)			((x >> 8) & 0x1f)
+#define SCU_D1_PLL_DENUM_MASK			(0x1f << 8)
+#define SCU_D1_PLL_SET_NUM(x)			(x & 0xff)
+#define SCU_D1_PLL_GET_NUM(x)			(x & 0xff)
+#define SCU_D1_PLL_NUM_MASK				(0xff)
+
+/*	AST_SCU_D2_PLL: 0x1C - D2-PLL Parameter  register */
+#define SCU_D2_PLL_SET_PD2(x)			((x & 0x7) << 19)
+#define SCU_D2_PLL_GET_PD2(x)			((x >> 19) & 0x7)
+#define SCU_D2_PLL_PD2_MASK				(0x7 << 19)
+#define SCU_D2_PLL_BYPASS_EN			(0x1 << 18)
+#define SCU_D2_PLL_OFF					(0x1 << 17)
+#define SCU_D2_PLL_SET_PD(x)			((x & 0x3) << 15)
+#define SCU_D2_PLL_GET_PD(x)			((x >> 15) & 0x3)
+#define SCU_D2_PLL_PD_MASK				(0x3 << 15)
+#define SCU_D2_PLL_SET_OD(x)			((x & 0x3) << 13)
+#define SCU_D2_PLL_GET_OD(x)			((x >> 13) & 0x3)
+#define SCU_D2_PLL_OD_MASK				(0x3 << 13)
+#define SCU_D2_PLL_SET_DENUM(x)			((x & 0x1f) << 8)
+#define SCU_D2_PLL_GET_DENUM(x)			((x >> 8) & 0x1f)
+#define SCU_D2_PLL_DENUM_MASK			(0x1f << 8)
+#define SCU_D2_PLL_SET_NUM(x)			(x & 0xff)
+#define SCU_D2_PLL_GET_NUM(x)			(x & 0xff)
+#define SCU_D2_PLL_NUM_MASK				(0xff)
+
+/*	AST_SCU_M_PLL : 0x20	- M-PLL Parameter register	*/
+#define SCU_M_PLL_BYPASS_EN				(0x1 << 17)
+#define SCU_M_PLL_OFF					(0x1 << 16)
+#define SCU_M_PLL_NUM(x)				((x & 0x3f) << 5)
+#define SCU_M_PLL_GET_NUM(x)			((x >> 5) & 0x3f)
+#define SCU_M_PLL_NUM_MASK				(0x3f << 5)
+#define SCU_M_PLL_OUT_DIV				(0x1 << 4)
+#define SCU_M_PLL_GET_DIV(x)			((x >> 4) & 0x1)
+#define SCU_M_PLL_SET_DENUM(x)			(x & 0xf)
+#define SCU_M_PLL_GET_DENUM(x)			(x & 0xf)
+
+/*	AST_SCU_H_PLL: 0x24- H-PLL Parameter register		*/
+#define SCU_H_PLL_BYPASS_EN				(0x1 << 17)
+#define SCU_H_PLL_OFF					(0x1 << 16)
+#define SCU_H_PLL_SET_NUM(x)			((x & 0x3f) << 5)
+#define SCU_H_PLL_GET_NUM(x)			((x >> 5) & 0x3f)
+#define SCU_H_PLL_NUM_MASK				(0x3f << 5)
+#define SCU_H_PLL_OUT_DIV				(0x1 << 4)
+#define SCU_H_PLL_GET_DIV(x)			((x >> 4) & 0x1)
+#define SCU_H_PLL_SET_DENUM(x)			(x & 0xf)
+#define SCU_H_PLL_GET_DENUM(x)			(x & 0xf)
+#define SCU_H_PLL_DENUM_MASK			(0xf)
+
+/*	AST_SCU_FREQ_LIMIT : 0x28 - frequency counter comparsion register */
+#define SCU_FREQ_U_LIMIT(x)			((x & 0x3fff) << 16)
+#define SCU_FREQ_U_LIMIT_MASK		(0x3fff << 16)
+#define SCU_FREQ_L_LIMIT(x)			(x & 0x3fff)
+#define SCU_FREQ_L_LIMIT_MASK		(0x3fff)
+
+/*	AST_SCU_MISC_CTRL : 0x2C - Misc. Control register */
+#define HPLL_MPLL	0
+#define HPLL_DIV2	1
+#define SCU_MISC_24MHZ_BCLK				(0x1 << 28)
+#define SCU_MISC_RFX_CLK_SEL(x)			((x & 0x1) << 27)
+#define SCU_MISC_RFX_CLK_HPLL_DIV2		(0x1 << 27)
+#define SCU_MISC_JTAG_MASTER_DIS		(0x1 << 26)
+#define SCU_MISC_ST_CLK_HPLL_DIV2		(0x1 << 25)
+#define SCU_MISC_H264_CLK_HPLL_DIV2		(0x1 << 24)
+#define SCU_MISC_AX_CLK_HPLL_DIV2		(0x1 << 23)
+#define SCU_MISC_BB_CLK_HPLL_DIV2		(0x1 << 22)
+#define SCU_MISC_D4_CLK_D2_PLL			(0x1 << 21)
+#define SCU_MISC_D3_CLK_D2_PLL			(0x1 << 20)
+#define SCU_MISC_D2_CLK_D2_PLL			(0x1 << 19)
+#define SCU_MISC_D1_CLK_D2_PLL			(0x1 << 18)
+#define SCU_MISC_DAC_MASK				(0x3 << 16)
+#define SCU_MISC_DAC_SOURCE_CRT			(0x1 << 16)		//00 VGA, 01: CRT, 1x: PASS-Through DVO
+#define SCU_MISC_DAC_SOURCE_MASK		(0x3 << 16)
+#define SCU_MISC_RST_CRT1_EN			(0x1 << 15)
+#define SCU_MISC_RST_CRT2_EN			(0x1 << 14)
+#define SCU_MISC_RST_CRT3_EN			(0x1 << 13)
+#define SCU_MISC_RST_CRT4_EN			(0x1 << 12)
+#define SCU_MISC_Y_CLK_INVERT			(0x1 << 11)
+
+#define SCU_MISC_OUT_DELAY				(0x1 << 9)
+#define SCU_MISC_PCI_TO_AHB_DIS			(0x1 << 8)
+//#define SCU_MISC_2D_CRT_EN				(0x1 << 7)
+//#define SCU_MISC_VGA_CRT_DIS			(0x1 << 6)
+//#define SCU_MISC_VGA_REG_ACCESS_EN		(0x1 << 5)
+#define SCU_MISC_D2_PLL_DIS				(0x1 << 4)
+#define SCU_MISC_DAC_DIS				(0x1 << 3)
+#define SCU_MISC_D1_PLL_DIS				(0x1 << 2)
+#define SCU_MISC_OSC_CLK_OUT_PIN		(0x1 << 1)
+//#define SCU_MISC_LPC_TO_SPI_DIS			(0x1 << 0)
+
+/*	AST_SCU_PCI_CONF1 : 0x30 - PCI configuration setting register#1 */
+#define SCU_PCI_DEVICE_ID(x)			(x << 16)
+#define SCU_PCI_VENDOR_ID(x)			(x)
+
+/*	AST_SCU_PCI_CONF2	0x34		PCI configuration setting register#2 */
+#define SCU_PCI_SUB_SYS_ID(x)			(x << 16)
+#define SCU_PCI_SUB_VENDOR_ID(x)		(x)
+
+/*	AST_SCU_PCI_CONF3	0x38		PCI configuration setting register#3 */
+#define SCU_PCI_CLASS_CODE(x)			(x << 8)
+#define SCU_PCI_REVISION_ID(x)			(x)
+
+/*	AST_SCU_SYS_CTRL	0x3C		System reset contrl/status register*/
+#define SCU_SYS_EXT_SOC_RESET_EN		(0x1 << 3)
+#define SCU_SYS_EXT_RESET_FLAG			(0x1 << 2)
+#define SCU_SYS_WDT_RESET_FLAG			(0x1 << 1)
+#define SCU_SYS_PWR_RESET_FLAG			(0x1 << 0)
+
+/*	AST_SCU_SOC_SCRATCH0	0x40		SOC scratch 0~31 register */
+
+
+
+
+/*	AST_SCU_SOC_SCRATCH1	0x44		SOC scratch 32~63 register */
+
+
+/*	AST_SCU_VGA0		0x40		VGA fuction handshake register */
+#define SCU_VGA_SLT_HANDSHAKE(x)		(x << 24)
+#define SCU_VGA_SLT_HANDSHAKE_MASK		(0xff << 24)
+#define SCU_VGA_CTM_DEF(x)				(x << 16)
+#define SCU_VGA_CTM_DEF_MASK			(0xff << 16)
+#define SCU_MAC0_PHY_MODE(x)			(x << 14)
+#define SCU_MAC0_GET_PHY_MODE(x)		((x >> 14) & 0x3)
+#define SCU_MAC0_PHY_MODE_MASK(x)		(0x3 << 14)
+#define SCU_MAC1_PHY_MODE(x)			(x << 12)
+#define SCU_MAC1_PHY_MODE_MASK			(0x3 << 12)
+#define SCU_MAC1_GET_PHY_MODE(x)		((x >> 12) & 0x3)
+
+#define SCU_VGA_ASPEED_DEF(x)			(x << 8)
+#define SCU_VGA_ASPEED_DEF_MASK			(0xf << 8)
+
+#define SCU_VGA_DRAM_INIT_MASK(x)		((x >> 7) & 0x1)
+
+/*	AST_SCU_VGA1		0x44		VGA fuction handshake register */
+
+
+/*	AST_SCU_MAC_CLK		0x48		MAC interface clock delay setting register */
+
+
+
+/*	AST_SCU_MISC_CTRL	0x4C		Misc. 2 Control register */
+/*	AST_SCU_VGA_SCRATCH0	0x50		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH1	0x54		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH2	0x58		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH3	0x5c		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH4	0x60		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH5	0x64		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH6	0x68		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH7	0x6c		VGA Scratch register */
+
+/*	AST_SCU_HW_STRAP1			0x70		hardware strapping register */
+#define SCU_HW_STRAP_SW_DEFINE(x)		(x << 29)
+#define SCU_HW_STRAP_SW_DEFINE_MASK		(0x3 << 29)
+#define SCU_HW_STRAP_DRAM_SIZE(x)		(x << 27)
+#define SCU_HW_STRAP_DRAM_SIZE_MASK		(0x3 << 27)
+
+#define VGA_64M_DRAM			0
+#define VGA_128M_DRAM			1
+#define VGA_256M_DRAM			2
+#define VGA_512M_DRAM			3
+
+#define SCU_HW_STRAP_DRAM_CONFIG(x)		((x & 0x7) << 24)
+#define SCU_HW_STRAP_DRAM_CONFIG_MASK	(0x7 << 24)
+
+#define SCU_HW_STRAP_SPI_MODE(x)			((x & 0x3) << 12)
+#define SCU_HW_STRAP_SPI_MODE_MASK			(0x3 << 12)
+#define SPI_MODE_DIS			(0)
+#define SPI_MODE_MASTER_EN		(1)
+#define SPI_MODE_M_S_EN			(2)
+#define SPI_MODE_PS				(3)
+
+#define SCU_HW_STRAP_SET_CPU_AHB_RATIO(x)		(x << 10)
+#define SCU_HW_STRAP_GET_CPU_AHB_RATIO(x)		((x >> 10) & 3)
+#define SCU_HW_STRAP_CPU_AHB_RATIO_MASK		(0x3 << 10)
+
+
+#define CPU_AHB_RATIO_1_1		0
+#define CPU_AHB_RATIO_2_1		1
+#define CPU_AHB_RATIO_4_1		2
+#define CPU_AHB_RATIO_3_1		3
+
+#define SCU_HW_STRAP_GET_H_PLL_CLK(x)	((x >> 8 )& 0x3)
+#define SCU_HW_STRAP_H_PLL_CLK_MASK		(0x3 << 8)
+#define CPU_384MHZ		0
+#define CPU_360MHZ		1
+#define CPU_336MHZ		2
+#define CPU_408MHZ		3
+
+//#define SCU_HW_STRAP_MAC1_INF		(0x1 << 7)
+#define SCU_HW_STRAP_MAC0_INF		(0x1 << 6)
+//#define SCU_HW_STRAP_VGA_BIOS_ROM	(0x1 << 5)
+#define SCU_HW_STRAP_SPI_WIDTH		(0x1 << 4)
+//#define SCU_HW_STRAP_VGA_SIZE_GET(x)		((x >> 2)& 0x3)
+
+#define SCU_HW_STRAP_BOOT_MODE(x)		(x)
+#define NOR_BOOT		0
+#define NAND_BOOT		1
+#define SPI_BOOT		2
+#define DIS_BOOT		3
+
+/*	AST_SCU_RAMDOM_GEN		0x74		random number generator register */
+/*	AST_SCU_RAMDOM_DATA		0x78		random number generator data output*/
+
+/*	AST_SCU_MULTI_FUNC_2	0x78 */
+
+/*	AST_SCU_REVISION_ID		0x7C		Silicon revision ID register */
+#define AST1100_A0				0x00000200
+#define AST1100_A1				0x00000201
+#define AST1100_A2				0x00000202
+#define AST1100_A3				0x00000202
+
+#define AST2050_A0				0x00000200
+#define AST2050_A1				0x00000201
+#define AST2050_A2				0x00000202
+#define AST2050_A3				0x00000202
+
+#define AST2100_A0				0x00000300
+#define AST2100_A1				0x00000301
+#define AST2100_A2				0x00000302
+#define AST2100_A3				0x00000302
+
+#define AST2200_A0				0x00000102
+#define AST2200_A1				0x00000102
+
+#define AST2300_A0				0x01000003
+#define AST2300_A1				0x01010303
+#define AST1300_A1				0x01010003
+#define AST1050_A1				0x01010203
+
+#define AST2400_A0				0x02000303
+
+
+/*	AST_SCU_FUN_PIN_CTRL1		0x80		Multi-function Pin Control#1*/
+#define SCU_FUN_PIN_UART4_RXD	(0x1 << 31)
+#define SCU_FUN_PIN_UART4_TXD	(0x1 << 30)
+#define SCU_FUN_PIN_UART4_NRTS	(0x1 << 29)
+#define SCU_FUN_PIN_UART4_NDTR	(0x1 << 28)
+#define SCU_FUN_PIN_UART4_NRI	(0x1 << 27)
+#define SCU_FUN_PIN_UART4_NDSR	(0x1 << 26)
+#define SCU_FUN_PIN_UART4_NDCD	(0x1 << 25)
+#define SCU_FUN_PIN_UART4_NCTS	(0x1 << 24)
+#define SCU_FUN_PIN_UART3_RXD	(0x1 << 23)
+#define SCU_FUN_PIN_UART3_TXD	(0x1 << 22)
+#define SCU_FUN_PIN_UART3_NRTS	(0x1 << 21)
+#define SCU_FUN_PIN_UART3_NDTR	(0x1 << 20)
+#define SCU_FUN_PIN_UART3_NRI	(0x1 << 19)
+#define SCU_FUN_PIN_UART3_NDSR	(0x1 << 18)
+#define SCU_FUN_PIN_UART3_NDCD	(0x1 << 17)
+#define SCU_FUN_PIN_UART3_NCTS	(0x1 << 16)
+#define SCU_FUN_PIN_SPICS1		(0x1 << 15)
+#define SCU_FUN_PIN_LPCPME		(0x1 << 14)
+#define SCU_FUN_PIN_LPCPD		(0x1 << 13)
+#define SCU_FUN_PIN_LPCRST		(0x1 << 12)
+#define SCU_FUN_PIN_I2C_SALT4	(0x1 << 11)
+#define SCU_FUN_PIN_I2C_SALT3	(0x1 << 10)
+#define SCU_FUN_PIN_I2C_SALT2	(0x1 << 9)
+#define SCU_FUN_PIN_I2C_SALT1	(0x1 << 8)
+#define SCU_FUN_PIN_TIMER8		(0x1 << 7)
+#define SCU_FUN_PIN_TIMER7		(0x1 << 6)
+#define SCU_FUN_PIN_TIMER6		(0x1 << 5)
+#define SCU_FUN_PIN_TIMER5		(0x1 << 4)
+#define SCU_FUN_PIN_TIMER4		(0x1 << 3)
+#define SCU_FUN_PIN_TIMER3		(0x1 << 2)
+#define SCU_FUN_PIN_MAC1_PHY_LINK	(0x1 << 1)
+#define SCU_FUN_PIN_MAC0_PHY_LINK	(0x1)
+
+/*	AST_SCU_FUN_PIN_CTRL2		0x84		Multi-function Pin Control#2*/
+#define SCU_FUN_PIN_VPIB9		(0x1 << 31)
+#define SCU_FUN_PIN_VPIB8		(0x1 << 30)
+#define SCU_FUN_PIN_VPIB7		(0x1 << 29)
+#define SCU_FUN_PIN_VPIB6		(0x1 << 28)
+#define SCU_FUN_PIN_VPIB5		(0x1 << 27)
+#define SCU_FUN_PIN_VPIB4		(0x1 << 26)
+#define SCU_FUN_PIN_VPIB3		(0x1 << 25)
+#define SCU_FUN_PIN_VPIB2		(0x1 << 24)
+#define SCU_FUN_PIN_VPIB1		(0x1 << 23)
+#define SCU_FUN_PIN_VPIB0		(0x1 << 22)
+#define SCU_FUN_PIN_VPICLK		(0x1 << 21)
+#define SCU_FUN_PIN_VPIVS		(0x1 << 20)
+#define SCU_FUN_PIN_VPIHS		(0x1 << 19)
+#define SCU_FUN_PIN_VPIODD		(0x1 << 18)
+#define SCU_FUN_PIN_VPIDE		(0x1 << 17)
+
+#define SCU_FUN_PIN_UART2_RXD	(0x1 << 31)
+#define SCU_FUN_PIN_UART2_TXD	(0x1 << 30)
+#define SCU_FUN_PIN_UART2_NRTS	(0x1 << 29)
+#define SCU_FUN_PIN_UART2_NDTR	(0x1 << 28)
+#define SCU_FUN_PIN_UART2_NRI	(0x1 << 27)
+#define SCU_FUN_PIN_UART2_NDSR	(0x1 << 26)
+#define SCU_FUN_PIN_UART2_NDCD	(0x1 << 25)
+#define SCU_FUN_PIN_UART2_NCTS	(0x1 << 24)
+#define SCU_FUN_PIN_UART1_RXD	(0x1 << 23)
+#define SCU_FUN_PIN_UART1_TXD	(0x1 << 22)
+#define SCU_FUN_PIN_UART1_NRTS	(0x1 << 21)
+#define SCU_FUN_PIN_UART1_NDTR	(0x1 << 20)
+#define SCU_FUN_PIN_UART1_NRI	(0x1 << 19)
+#define SCU_FUN_PIN_UART1_NDSR	(0x1 << 18)
+#define SCU_FUN_PIN_UART1_NDCD	(0x1 << 17)
+#define SCU_FUN_PIN_UART1_NCTS	(0x1 << 16)
+
+
+#define SCU_FUN_PIN_NAND_FLWP	(0x1 << 7)
+#define SCU_FUN_PIN_NAND_FLBUSY	(0x1 << 6)
+
+/*	AST_SCU_FUN_PIN_CTRL3		0x88		Multi-function Pin Control#3*/
+#define SCU_FUN_PIN_MAC0_MDIO	(0x1 << 31)
+#define SCU_FUN_PIN_MAC0_MDC	(0x1 << 30)
+#define SCU_FUN_PIN_ROMA25		(0x1 << 29)
+#define SCU_FUN_PIN_ROMA24		(0x1 << 28)
+#define SCU_FUN_PIN_ROMCS4		(0x1 << 27)
+#define SCU_FUN_PIN_ROMCS3		(0x1 << 26)
+#define SCU_FUN_PIN_ROMCS2		(0x1 << 25)
+#define SCU_FUN_PIN_ROMCS1		(0x1 << 24)
+#define SCU_FUN_PIN_ROMCS(x)	(0x1 << (23+x))
+
+//Video pin
+#define SCU_FUN_PIN_VPIR9		(0x1 << 19)
+#define SCU_FUN_PIN_VPIR8		(0x1 << 18)
+#define SCU_FUN_PIN_VPIR7		(0x1 << 17)
+#define SCU_FUN_PIN_VPIR6		(0x1 << 16)
+#define SCU_FUN_PIN_VPIR5		(0x1 << 15)
+#define SCU_FUN_PIN_VPIR4		(0x1 << 14)
+#define SCU_FUN_PIN_VPIR3		(0x1 << 13)
+#define SCU_FUN_PIN_VPIR2		(0x1 << 12)
+#define SCU_FUN_PIN_VPIR1		(0x1 << 11)
+#define SCU_FUN_PIN_VPIR0		(0x1 << 10)
+#define SCU_FUN_PIN_VPIG9		(0x1 << 9)
+#define SCU_FUN_PIN_VPIG8		(0x1 << 8)
+#define SCU_FUN_PIN_VPIG7		(0x1 << 7)
+#define SCU_FUN_PIN_VPIG6		(0x1 << 6)
+#define SCU_FUN_PIN_VPIG5		(0x1 << 5)
+#define SCU_FUN_PIN_VPIG4		(0x1 << 4)
+#define SCU_FUN_PIN_VPIG3		(0x1 << 3)
+#define SCU_FUN_PIN_VPIG2		(0x1 << 2)
+#define SCU_FUN_PIN_VPIG1		(0x1 << 1)
+#define SCU_FUN_PIN_VPIG0		(0x1 << 0)
+
+//pwm pin
+#define SCU_FUN_PIN_PWM_TACHO	(0)
+
+/*	AST_SCU_FUN_PIN_CTRL4		0x8C		Multi-function Pin Control#4*/
+#define SCU_FUN_PIN_ROMA23		(0x1 << 7)
+#define SCU_FUN_PIN_ROMA22		(0x1 << 6)
+
+#define SCU_FUN_PIN_ROMWE		(0x1 << 5)
+#define SCU_FUN_PIN_ROMOE		(0x1 << 4)
+#define SCU_FUN_PIN_ROMD7		(0x1 << 3)
+#define SCU_FUN_PIN_ROMD6		(0x1 << 2)
+#define SCU_FUN_PIN_ROMD5		(0x1 << 1)
+#define SCU_FUN_PIN_ROMD4		(0x1)
+
+/*	AST_SCU_FUN_PIN_CTRL5		0x90		Multi-function Pin Control#5*/
+#define SCU_FUN_PIN_SPICS1		(0x1 << 31)
+#define SCU_FUN_PIN_LPC_PLUS	(0x1 << 30)
+#define SCU_FUC_PIN_USB20_HOST	(0x1 << 29)
+#define SCU_FUC_PIN_USB11_PORT4	(0x1 << 28)
+#define SCU_FUC_PIN_I2C14		(0x1 << 27)
+#define SCU_FUC_PIN_I2C13		(0x1 << 26)
+#define SCU_FUC_PIN_I2C12		(0x1 << 25)
+#define SCU_FUC_PIN_I2C11		(0x1 << 24)
+#define SCU_FUC_PIN_I2C10		(0x1 << 23)
+#define SCU_FUC_PIN_I2C9		(0x1 << 22)
+#define SCU_FUC_PIN_I2C8		(0x1 << 21)
+#define SCU_FUC_PIN_I2C7		(0x1 << 20)
+#define SCU_FUC_PIN_I2C6		(0x1 << 19)
+#define SCU_FUC_PIN_I2C5		(0x1 << 18)
+#define SCU_FUC_PIN_I2C4		(0x1 << 17)
+#define SCU_FUC_PIN_I2C3		(0x1 << 16)
+#define SCU_FUC_PIN_MII2_RX_DWN_DIS		(0x1 << 15)
+#define SCU_FUC_PIN_MII2_TX_DWN_DIS		(0x1 << 14)
+#define SCU_FUC_PIN_MII1_RX_DWN_DIS		(0x1 << 13)
+#define SCU_FUC_PIN_MII1_TX_DWN_DIS		(0x1 << 12)
+
+#define SCU_FUC_PIN_MII2_TX_DRIV(x)		(x << 10)
+#define SCU_FUC_PIN_MII2_TX_DRIV_MASK	(0x3 << 10)
+#define SCU_FUC_PIN_MII1_TX_DRIV(x)		(x << 8)
+#define SCU_FUC_PIN_MII1_TX_DRIV_MASK	(0x3 << 8)
+
+#define MII_NORMAL_DRIV	0x0
+#define MII_HIGH_DRIV	0x2
+
+#define SCU_FUC_PIN_UART6		(0x1 << 7)
+#define SCU_FUC_PIN_ROM_16BIT	(0x1 << 6)
+#define SCU_FUC_PIN_DIGI_V_OUT(x)	(x << 4)
+#define SCU_FUC_PIN_DIGI_V_OUT_MASK	(0x3 << 4)
+
+#define VIDEO_DISABLE	0x0
+#define VIDEO_12BITS	0x1
+#define VIDEO_24BITS	0x2
+//#define VIDEO_DISABLE	0x3
+
+#define SCU_FUC_PIN_USB11_PORT2	(0x1 << 3)
+#define SCU_FUC_PIN_MAC1_MDIO		(0x1 << 2)
+#define SCU_FUC_PIN_SD2		(0x1 << 1)
+#define SCU_FUC_PIN_SD1		(0x1 << 0)
+
+
+/*	AST_SCU_FUN_PIN_CTRL6		0x94		Multi-function Pin Control#6*/
+#define SCU_VIDEO_OUT_MASK		(~0x3)
+
+/*	AST_SCU_WDT_RESET		0x9C		Watchdog Reset Selection */
+/*	AST_SCU_FUN_PIN_CTRL7		0xA0		Multi-function Pin Control#7*/
+/*	AST_SCU_FUN_PIN_CTRL8		0xA4		Multi-function Pin Control#8*/
+#define SCU_FUN_PIN_ROMA17		(0x1 << 31)
+#define SCU_FUN_PIN_ROMA16		(0x1 << 30)
+#define SCU_FUN_PIN_ROMA15		(0x1 << 29)
+#define SCU_FUN_PIN_ROMA14		(0x1 << 28)
+#define SCU_FUN_PIN_ROMA13		(0x1 << 27)
+#define SCU_FUN_PIN_ROMA12		(0x1 << 26)
+#define SCU_FUN_PIN_ROMA11		(0x1 << 25)
+#define SCU_FUN_PIN_ROMA10		(0x1 << 24)
+#define SCU_FUN_PIN_ROMA9		(0x1 << 23)
+#define SCU_FUN_PIN_ROMA8		(0x1 << 22)
+#define SCU_FUN_PIN_ROMA7		(0x1 << 21)
+#define SCU_FUN_PIN_ROMA6		(0x1 << 20)
+#define SCU_FUN_PIN_ROMA5		(0x1 << 19)
+#define SCU_FUN_PIN_ROMA4		(0x1 << 18)
+#define SCU_FUN_PIN_ROMA3		(0x1 << 17)
+#define SCU_FUN_PIN_ROMA2		(0x1 << 16)
+
+/*	AST_SCU_FUN_PIN_CTRL9		0xA8		Multi-function Pin Control#9*/
+#define SCU_FUN_PIN_ROMA21		(0x1 << 3)
+#define SCU_FUN_PIN_ROMA20		(0x1 << 2)
+#define SCU_FUN_PIN_ROMA19		(0x1 << 1)
+#define SCU_FUN_PIN_ROMA18		(0x1)
+
+/*	AST_SCU_PWR_SAVING_EN		0xC0		Power Saving Wakeup Enable*/
+/*	AST_SCU_PWR_SAVING_CTRL		0xC4		Power Saving Wakeup Control*/
+/*	AST_SCU_HW_STRAP2			0xD0		Haardware strapping register set 2*/
+/*	AST_SCU_COUNTER4			0xE0		SCU Free Run Counter Read Back #4*/
+/*	AST_SCU_COUNTER4_EXT		0xE4		SCU Free Run Counter Extended Read Back #4*/
+
+//CPU 2 
+/*	AST_SCU_CPU2_CTRL			0x100		CPU2 Control Register*/
+/*	AST_SCU_CPU2_BASE0_ADDR		0x104		CPU2 Base Address for Segment 0x00:0000~0x1F:FFFF*/
+/*	AST_SCU_CPU2_BASE1_ADDR		0x108		CPU2 Base Address for Segment 0x20:0000~0x3F:FFFF*/
+/*	AST_SCU_CPU2_BASE2_ADDR		0x10C		CPU2 Base Address for Segment 0x40:0000~0x5F:FFFF*/
+/*	AST_SCU_CPU2_BASE3_ADDR		0x110		CPU2 Base Address for Segment 0x60:0000~0x7F:FFFF*/
+/*	AST_SCU_CPU2_BASE4_ADDR		0x114		CPU2 Base Address for Segment 0x80:0000~0xFF:FFFF*/
+/*	AST_SCU_CPU2_CACHE_CTRL		0x118		CPU2 Cache Function Control */
+
+//
+/*	AST_SCU_UART24_REF			0x160		Generate UART 24Mhz Ref from H-PLL when CLKIN is 25Mhz */
+/*	AST_SCU_PCIE_CONFIG_SET		0x180		PCI-E Configuration Setting Control Register */
+/*	AST_SCU_BMC_MMIO_DEC		0x184		BMC MMIO Decode Setting Register */
+/*	AST_SCU_DEC_AREA1			0x188		1st relocated controller decode area location */
+/*	AST_SCU_DEC_AREA2			0x18C		2nd relocated controller decode area location */
+/*	AST_SCU_MBOX_DEC_AREA		0x190		Mailbox decode area location*/
+/*	AST_SCU_SRAM_DEC_AREA0		0x194		Shared SRAM area decode location*/
+/*	AST_SCU_SRAM_DEC_AREA1		0x198		Shared SRAM area decode location*/
+/*	AST_SCU_BMC_CLASS			0x19C		BMC device class code and revision ID */
+/*	AST_SCU_BMC_DEV_ID			0x1A4		BMC device ID */
+
+#endif	/* __AST_SCU_G5_REGS_H */
+
diff --git a/arch/arm/plat-aspeed/include/plat/regs-scu.h b/arch/arm/plat-aspeed/include/plat/regs-scu.h
new file mode 100644
index 0000000..0abdcbd
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-scu.h
@@ -0,0 +1,740 @@
+/* arch/arm/mach-aspeed/include/mach/regs-ast2300-scu.h
+ *
+ * Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *   History      : 
+ *    1. 2012/12/29 Ryan Chen Create
+ * 
+********************************************************************************/
+#ifndef __AST_SCU_H
+#define __AST_SCU_H                     1
+
+/*
+ *  Register for SCU
+ *  */
+#define AST_SCU_PROTECT		0x00		/*	protection key register	*/
+#define AST_SCU_RESET		0x04		/*	system reset control register */
+#define AST_SCU_CLK_SEL		0x08		/*	clock selection register	*/
+#define AST_SCU_CLK_STOP	0x0C		/*	clock stop control register	*/
+#define AST_SCU_COUNT_CTRL	0x10		/*	frequency counter control register	*/
+#define AST_SCU_COUNT_VAL	0x14		/*	frequency counter measure register 	*/
+#define AST_SCU_INTR_CTRL	0x18		/*	Interrupt control and status register	*/
+#define AST_SCU_D2_PLL		0x1C		/*	D2-PLL Parameter  register	*/
+#define AST_SCU_M_PLL		0x20		/*	M-PLL Parameter register		*/
+#define AST_SCU_H_PLL		0x24		/*	H-PLL Parameter register		*/
+#define AST_SCU_FREQ_LIMIT	0x28		/*	frequency counter comparsion register */
+#define AST_SCU_MISC1_CTRL	0x2C		/*	Misc. Control register */
+#define AST_SCU_PCI_CONF1	0x30		/*	PCI configuration setting register#1 */
+#define AST_SCU_PCI_CONF2	0x34		/*	PCI configuration setting register#2 */
+#define AST_SCU_PCI_CONF3	0x38		/*	PCI configuration setting register#3 */
+#define AST_SCU_SYS_CTRL	0x3C		/*	System reset contrl/status register*/
+#define AST_SCU_SOC_SCRATCH0	0x40		/*	SOC scratch 0~31 register */
+#define AST_SCU_SOC_SCRATCH1	0x44		/*	SOC scratch 32~63 register */
+#define AST_SCU_VGA0		0x40		/*	VGA fuction handshake register */
+#define AST_SCU_VGA1		0x44		/*	VGA fuction handshake register */
+#define AST_SCU_MAC_CLK		0x48		/*	MAC interface clock delay setting register */
+#define AST_SCU_MISC2_CTRL	0x4C		/*	Misc. 2 Control register */
+#define AST_SCU_VGA_SCRATCH0	0x50		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH1	0x54		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH2	0x58		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH3	0x5c		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH4	0x60		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH5	0x64		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH6	0x68		/*	VGA Scratch register */
+#define AST_SCU_VGA_SCRATCH7	0x6c		/*	VGA Scratch register */
+#define AST_SCU_HW_STRAP1			0x70		/*	hardware strapping register */
+#define AST_SCU_RAMDOM_GEN		0x74		/*	random number generator register */
+#if defined(CONFIG_ARCH_1100) || defined(CONFIG_ARCH_2050) || defined(CONFIG_ARCH_2100) || defined(CONFIG_ARCH_2200)
+#define AST_SCU_MULTI_FUNC_2	0x78
+#else
+#define AST_SCU_RAMDOM_DATA		0x78		/*	random number generator data output*/
+#endif
+#define AST_SCU_REVISION_ID		0x7C		/*	Silicon revision ID register */
+#define AST_SCU_FUN_PIN_CTRL1		0x80		/*	Multi-function Pin Control#1*/
+#define AST_SCU_FUN_PIN_CTRL2		0x84		/*	Multi-function Pin Control#2*/
+#define AST_SCU_FUN_PIN_CTRL3		0x88		/*	Multi-function Pin Control#3*/
+#define AST_SCU_FUN_PIN_CTRL4		0x8C		/*	Multi-function Pin Control#4*/
+#define AST_SCU_FUN_PIN_CTRL5		0x90		/*	Multi-function Pin Control#5*/
+#define AST_SCU_FUN_PIN_CTRL6		0x94		/*	Multi-function Pin Control#6*/
+#define AST_SCU_WDT_RESET		0x9C		/*	Watchdog Reset Selection */
+#define AST_SCU_FUN_PIN_CTRL7		0xA0		/*	Multi-function Pin Control#7*/
+#define AST_SCU_FUN_PIN_CTRL8		0xA4		/*	Multi-function Pin Control#8*/
+#define AST_SCU_FUN_PIN_CTRL9		0xA8		/*	Multi-function Pin Control#9*/
+#define AST_SCU_PWR_SAVING_EN		0xC0		/*	Power Saving Wakeup Enable*/
+#define AST_SCU_PWR_SAVING_CTRL		0xC4		/*	Power Saving Wakeup Control*/
+#define AST_SCU_HW_STRAP2			0xD0		/*	Haardware strapping register set 2*/
+#define AST_SCU_COUNTER4			0xE0		/*	SCU Free Run Counter Read Back #4*/
+#define AST_SCU_COUNTER4_EXT		0xE4		/*	SCU Free Run Counter Extended Read Back #4*/
+
+//CPU 2 
+#define AST_SCU_CPU2_CTRL			0x100		/*	CPU2 Control Register*/
+#define AST_SCU_CPU2_BASE0_ADDR		0x104		/*	CPU2 Base Address for Segment 0x00:0000~0x1F:FFFF*/
+#define AST_SCU_CPU2_BASE1_ADDR		0x108		/*	CPU2 Base Address for Segment 0x20:0000~0x3F:FFFF*/
+#define AST_SCU_CPU2_BASE2_ADDR		0x10C		/*	CPU2 Base Address for Segment 0x40:0000~0x5F:FFFF*/
+#define AST_SCU_CPU2_BASE3_ADDR		0x110		/*	CPU2 Base Address for Segment 0x60:0000~0x7F:FFFF*/
+#define AST_SCU_CPU2_BASE4_ADDR		0x114		/*	CPU2 Base Address for Segment 0x80:0000~0xFF:FFFF*/
+#define AST_SCU_CPU2_CACHE_CTRL		0x118		/*	CPU2 Cache Function Control */
+
+//
+#define AST_SCU_UART24_REF			0x160		/*	Generate UART 24Mhz Ref from H-PLL when CLKIN is 25Mhz */
+#define AST_SCU_PCIE_CONFIG_SET		0x180		/*	PCI-E Configuration Setting Control Register */
+#define AST_SCU_BMC_MMIO_DEC		0x184		/*	BMC MMIO Decode Setting Register */
+#define AST_SCU_DEC_AREA1			0x188		/*	1st relocated controller decode area location */
+#define AST_SCU_DEC_AREA2			0x18C		/*	2nd relocated controller decode area location */
+#define AST_SCU_MBOX_DEC_AREA		0x190		/*	Mailbox decode area location*/
+#define AST_SCU_SRAM_DEC_AREA0		0x194		/*	Shared SRAM area decode location*/
+#define AST_SCU_SRAM_DEC_AREA1		0x198		/*	Shared SRAM area decode location*/
+#define AST_SCU_BMC_CLASS			0x19C		/*	BMC device class code and revision ID */
+#define AST_SCU_BMC_DEV_ID			0x1A4		/*	BMC device ID */
+
+
+/*	AST_SCU_PROTECT: 0x00  - protection key register */
+#define SCU_PROTECT_UNLOCK			0x1688A8A8
+
+/*	AST_SCU_RESET :0x04	 - system reset control register */
+#if defined (CONFIG_ARCH_AST1010)
+#define SCU_RESET_ADC				(0x1 << 6)
+#define SCU_RESET_JTAG				(0x1 << 5)
+#define SCU_RESET_MAC0				(0x1 << 4)
+#define SCU_RESET_PECI				(0x1 << 3)
+#define SCU_RESET_PWM				(0x1 << 2)
+#define SCU_RESET_LPC				(0x1 << 1)
+#define SCU_RESET_I2C				(0x1)
+#else
+#define SCU_RESET_X_DMA				(0x1 << 25)
+#define SCU_RESET_MCTP				(0x1 << 24)
+#define SCU_RESET_ADC				(0x1 << 23)
+#define SCU_RESET_JTAG				(0x1 << 22)
+#define SCU_PWAKE_PIN_EN			(0x1 << 20)
+#define SCU_PWAKE_PIN_OUT			(0x1 << 19)
+#define SCU_RESET_MIC				(0x1 << 18)
+#define SCU_RESET_RESV				(0x1 << 17) //must keep 1 
+#define SCU_RESET_SD				(0x1 << 16)
+#define SCU_RESET_USB11				(0x1 << 15)
+#define SCU_RESET_USB20				(0x1 << 14)
+#define SCU_RESET_CRT				(0x1 << 13)
+#define SCU_RESET_MAC1				(0x1 << 12)
+#define SCU_RESET_MAC0				(0x1 << 11)
+#define SCU_RESET_PECI				(0x1 << 10)
+#define SCU_RESET_PWM				(0x1 << 9)
+#define SCU_PCI_VGA_DIS				(0x1 << 8)
+#define SCU_RESET_2D				(0x1 << 7)
+#define SCU_RESET_VIDEO				(0x1 << 6)
+#define SCU_RESET_LPC				(0x1 << 5)
+#define SCU_RESET_HAC				(0x1 << 4)
+#define SCU_RESET_USB11_HID			(0x1 << 3)
+#define SCU_RESET_I2C				(0x1 << 2)
+#define SCU_RESET_AHB				(0x1 << 1)
+#define SCU_RESET_SRAM_CTRL			(0x1 << 0)
+#endif
+
+/*	AST_SCU_CLK_SEL	 : 0x08 - clock selection register	*/
+#if defined(CONFIG_ARCH_AST1010)
+#define SCU_CLK_MAC_DIV(x)			(x << 12)
+#define SCU_CLK_MAC_MASK			(0x3 << 12)
+#define SCU_LHCLK_SOURCE_EN			(0x1 << 11)		//0: ext , 1:internel
+#define SCU_LHCLK_LPC_DIV(x)		(x << 8)
+#define SCU_LHCLK_LPC_MASK			(0x7 << 8)
+#define SCU_PCLK_APB_DIV(x)			(x << 5)
+#define SCU_GET_PCLK_DIV(x)			((x >> 5) & 0x7)
+#define SCU_PCLK_APB_DIV_MASK		(0x7 << 5)		//limitation on PCLK .. PCLK > 0.5*LCLK (33Mhz)
+#define SCU_CLK_CPU_AHB_SLOW_EN		(0x1 << 4)
+#define SCU_CLK_CPU_AHB_SLOW(x)		(x << 3)
+#define SCU_CLK_CPU_AHB_SLOW_MASK	(0x3 << 3)
+#define SCU_GET_AHB_DIV(x)			((x >> 3) & 0x3)
+#define SCU_CLK_CPU_AHB_SLOW_IDLE	(0x1 << 1)
+#define SCU_CLK_CPU_AHB_DYN_SLOW_EN	(0x1)
+#else
+#define SCU_CLK_VIDEO_SLOW_EN		(0x1 << 31)
+#define SCU_CLK_VIDEO_SLOW_SET(x)	(x << 28)
+#define SCU_CLK_VIDEO_SLOW_MASK		(0x7 << 28)
+#define SCU_CLK_2D_ENG_GCLK_INVERT	(0x1 << 27)		//valid only at CRT mode SCU2C[7]
+#define SCU_CLK_2D_ENG_THROT_EN		(0x1 << 26)		//valid only at CRT mode SCU2C[7]
+#define SCU_PCLK_APB_DIV(x)			(x << 23)
+#define SCU_GET_PCLK_DIV(x)			((x >> 23) & 0x7)
+#define SCU_PCLK_APB_DIV_MASK		(0x7 << 23)		//limitation on PCLK .. PCLK > 0.5*LCLK (33Mhz)
+#define SCU_GET_LHCLK_DIV(x)		((x >> 20) & 0x7)
+#define SCU_SET_LHCLK_DIV(x)		(x << 20)
+#define SCU_LHCLK_DIV_MASK			(0x7 << 20)
+#define SCU_LHCLK_SOURCE_EN			(0x1 << 19)		//0: ext , 1:internel
+#define SCU_CLK_MAC_DIV(x)			(x << 16)
+#define SCU_CLK_MAC_MASK			(0x7 << 16)
+#define SCU_CLK_SD_EN				(0x1 << 15)
+#define SCU_CLK_SD_DIV(x)			(x << 12)
+#define SCU_CLK_SD_GET_DIV(x)		((x >> 12) & 0x7)
+#define SCU_CLK_SD_MASK				(0x7 << 12)
+#define SCU_CLK_VIDEO_DELAY(x)		(x << 8)
+#define SCU_CLK_VIDEO_DELAY_MASK	(0xf << 8)
+#define SCU_CLK_CPU_AHB_SLOW_EN		(0x1 << 7)
+#define SCU_CLK_CPU_AHB_SLOW(x)		(x << 4)
+#define SCU_CLK_CPU_AHB_SLOW_MASK	(0x7 << 4)
+#define SCU_GET_AHB_DIV(x)			((x >> 4) & 0x7)
+#define SCU_ECLK_SOURCE(x)			(x << 2)
+#define SCU_ECLK_SOURCE_MASK		(0x3 << 2)
+#define SCU_CLK_CPU_AHB_SLOW_IDLE	(0x1 << 1)
+#define SCU_CLK_CPU_AHB_DYN_SLOW_EN	(0x1 << 0)
+
+#endif
+
+/*	AST_SCU_CLK_STOP : 0x0C - clock stop control register	*/
+#if defined(CONFIG_ARCH_AST1010)
+#define SCU_LHCLK_STOP_EN			(0x1 << 7)
+#define SCU_MAC0CLK_STOP_EN			(0x1 << 6)
+#define SCU_UART3_CLK_STOP_EN		(0x1 << 5)
+#define SCU_UART2_CLK_STOP_EN		(0x1 << 4)
+#define SCU_UART1_CLK_STOP_EN		(0x1 << 3)
+#define SCU_LCLK_STOP_EN			(0x1 << 2)
+#define SCU_REFCLK_STOP_EN			(0x1 << 1)
+#define SCU_MCLK_STOP_EN			(0x1)
+#else
+#define SCU_LHCLK_STOP_EN			(0x1 << 28)
+#define SCU_SDCLK_STOP_EN			(0x1 << 27)
+#define SCU_UART4CLK_STOP_EN		(0x1 << 26)
+#define SCU_UART3CLK_STOP_EN		(0x1 << 25)
+#define SCU_RSACLK_STOP_EN			(0x1 << 24)
+//bit 22~23 must keep 1 
+#define SCU_MAC1CLK_STOP_EN			(0x1 << 21)
+#define SCU_MAC0CLK_STOP_EN			(0x1 << 20)
+//bit 18~19 must keep 1 
+#define SCU_UART5_CLK_STOP_EN		(0x1 << 17)
+#define SCU_UART2_CLK_STOP_EN		(0x1 << 16)
+#define SCU_UART1_CLK_STOP_EN		(0x1 << 15)
+#define SCU_USB20_CLK_EN			(0x1 << 14)
+#define SCU_YCLK_STOP_EN			(0x1 << 13)
+#define SCU_D2CLK_STOP_EN			(0x1 << 10)
+#define SCU_USB11CLK_STOP_EN		(0x1 << 9)
+#define SCU_LCLK_STOP_EN			(0x1 << 8)
+#define SCU_UCLK_STOP_EN			(0x1 << 7)
+#define SCU_REFCLK_STOP_EN			(0x1 << 6)
+#define SCU_DCLK_STOP_EN			(0x1 << 5)
+#define SCU_SACLK_STOP_EN			(0x1 << 4)
+#define SCU_VCLK_STOP_EN			(0x1 << 3)
+#define SCU_MCLK_STOP_EN			(0x1 << 2)
+#define SCU_GCLK_STOP_EN			(0x1 << 1)
+#define SCU_ECLK_STOP_EN			(0x1 << 0)
+#endif
+
+/* AST_SCU_COUNT_CTRL : 0x10 - frequency counter control register	*/
+#define SCU_FREQ_COMP_RESULT			(0x1 << 7) 
+#define SCU_FREQ_MEASU_FINISH			(0x1 << 6)
+#define SCU_FREQ_SOURCE_FOR_MEASU(x)	(x << 2)
+#define SCU_FREQ_SOURCE_FOR_MEASU_MASK	(0xf << 2)
+
+#define SCU_SOURCE_6M					0xf
+#define SCU_SOURCE_12M					0xe
+#define SCU_SOURCE_I2SM_CLK				0xd
+#define SCU_SOURCE_H_CLK				0xc
+#define SCU_SOURCE_B_CLK				0xb
+#define SCU_SOURCE_D2_PLL				0xa
+
+#define SCU_SOURCE_VIDEO_CLK			0x7
+#define SCU_SOURCE_LPC_CLK				0x6
+#define SCU_SOURCE_I2S_CLK				0x5
+#define SCU_SOURCE_M_CLK				0x4
+#define SCU_SOURCE_SALI_CLK				0x3
+#define SCU_SOURCE_D_PLL				0x2
+#define SCU_SOURCE_NAND					0x1
+#define SCU_SOURCE_DEL_CELL				0x0
+
+#define SCU_OSC_COUNT_EN				(0x1 << 1)
+#define SCU_RING_OSC_EN					(0x1 << 0)
+
+
+/*  AST_SCU_INTR_CTRL : 0x18 - Interrupt control and status register   */
+#define INTR_LPC_H_L_RESET				(0x1 << 21)
+#define INTR_LPC_L_H_RESET				(0x1 << 20)
+#define INTR_PCIE_H_L_RESET				(0x1 << 19)
+#define INTR_PCIE_L_H_RESET				(0x1 << 18)
+#define INTR_VGA_SCRATCH_CHANGE			(0x1 << 17)
+#define INTR_VGA_CURSOR_CHANGE			(0x1 << 16)
+#define INTR_MSI_EN						(0x1 << 6)
+#define INTR_LPC_H_L_RESET_EN			(0x1 << 5)
+#define INTR_LPC_L_H_RESET_EN			(0x1 << 4)
+#define INTR_PCIE_H_L_RESET_EN			(0x1 << 3)
+#define INTR_PCIE_L_H_RESET_EN			(0x1 << 2)
+#define INTR_VGA_SCRATCH_CHANGE_EN		(0x1 << 1)
+#define INTR_VGA_CURSOR_CHANGE_EN		(0x1 << 0)
+
+/*	AST_SCU_D2_PLL: 0x1C - D2-PLL Parameter  register */
+#define SCU_D2_PLL_SET_PD2(x)			(x << 19)
+#define SCU_D2_PLL_GET_PD2(x)			((x >> 19)&0x7)
+#define SCU_D2_PLL_PD2_MASK				(0x7 << 19)
+#define SCU_D2_PLL_BYPASS_EN			(0x1 << 18)
+#define SCU_D2_PLL_OFF					(0x1 << 17)
+#define SCU_D2_PLL_SET_PD(x)			(x << 15)
+#define SCU_D2_PLL_GET_PD(x)			((x >> 15) &0x3)
+#define SCU_D2_PLL_PD_MASK				(0x3 << 15)
+#define SCU_D2_PLL_SET_OD(x)			(x << 13)
+#define SCU_D2_PLL_GET_OD(x)			((x >> 13) & 0x3)
+#define SCU_D2_PLL_OD_MASK				(0x3 << 13)
+#define SCU_D2_PLL_SET_DENUM(x)			(x << 8)
+#define SCU_D2_PLL_GET_DENUM(x)			((x >>8)&0x1f)
+#define SCU_D2_PLL_DENUM_MASK			(0x1f << 8)
+#define SCU_D2_PLL_SET_NUM(x)			(x)
+#define SCU_D2_PLL_GET_NUM(x)			(x & 0xff)
+#define SCU_D2_PLL_NUM_MASK				(0xff)
+
+
+/*	AST_SCU_M_PLL : 0x20	- M-PLL Parameter register	*/
+#define SCU_M_PLL_BYPASS_EN				(0x1 << 17)
+#define SCU_M_PLL_OFF					(0x1 << 16)
+#define SCU_M_PLL_NUM(x)				(x << 5)
+#define SCU_M_PLL_GET_NUM(x)			((x >> 5) & 0x3f)
+#define SCU_M_PLL_NUM_MASK				(0x3f << 5)
+#define SCU_M_PLL_OUT_DIV				(0x1 << 4)
+#define SCU_M_PLL_GET_DIV(x)			((x >> 4) & 0x1)
+#define SCU_M_PLL_DENUM(x)				(x)
+#define SCU_M_PLL_GET_DENUM(x)			(x & 0xf)
+
+
+/*	AST_SCU_H_PLL: 0x24- H-PLL Parameter register		*/
+#if defined(CONFIG_ARCH_AST1010)
+#define SCU_H_PLL_MASK_EN				(0x1 << 10)
+#define SCU_H_PLL_REST_EN				(0x1 << 9)
+#define SCU_H_PLL_OUT_DIV(x)			(x << 7)
+#define SCU_H_PLL_GET_DIV(x)			((x >> 7) & 0x3)
+#define SCU_H_PLL_GET_DENUM(x)			((x >> 6) & 0x1)
+#define SCU_H_PLL_NUM(x)				(x)
+#define SCU_H_PLL_GET_NUM(x)			(x & 0x3f)
+#define SCU_H_PLL_NUM_MASK				(0x3f)
+
+#else
+#define SCU_H_PLL_PARAMETER				(0x1 << 18)
+#define SCU_H_PLL_BYPASS_EN				(0x1 << 17)
+#define SCU_H_PLL_OFF					(0x1 << 16)
+#define SCU_H_PLL_NUM(x)				(x << 5)
+#define SCU_H_PLL_GET_NUM(x)			((x >> 5) & 0x3f)
+#define SCU_H_PLL_NUM_MASK				(0x3f << 5)
+#define SCU_H_PLL_OUT_DIV				(0x1 << 4)
+#define SCU_H_PLL_GET_DIV(x)			((x >> 4) & 0x1)
+#define SCU_H_PLL_DENUM(x)				(x)
+#define SCU_H_PLL_GET_DENUM(x)			(x & 0xf)
+#define SCU_H_PLL_DENUM_MASK			(0xf)
+#endif
+
+/*	AST_SCU_FREQ_LIMIT : 0x28 - frequency counter comparsion register */
+#define SCU_FREQ_U_LIMIT(x)			(x << 16)
+#define SCU_FREQ_U_LIMIT_MASK		(0x3fff << 16)
+#define SCU_FREQ_L_LIMIT(x)			(x)
+#define SCU_FREQ_L_LIMIT_MASK		(0x3fff)
+
+
+/*	AST_SCU_MISC_CTRL : 0x2C - Misc. Control register */
+#define SCU_MISC_JTAG_MASTER_DIS	(0x1 << 26)
+#define SCU_MISC_DRAM_W_P2A_DIS		(0x1 << 25)
+#define SCU_MISC_SPI_W_P2A_DIS		(0x1 << 24)
+#define SCU_MISC_SOC_W_P2A_DIS		(0x1 << 23)
+#define SCU_MISC_FLASH_W_P2A_DIS	(0x1 << 22)
+#define SCU_MISC_D_PLL_ASSIGN(x)	(x << 20)
+#define SCU_MISC_D_PLL_ASSIGN_MASK	(0x3 << 20)
+#define SCU_MISC_VGA_CONFIG_PREFETCH	(0x1 << 19)
+#define SCU_MISC_DVO_SOURCE_CRT			(0x1 << 18) 	//0:VGA , 1:CRT
+#define SCU_MISC_DAC_MASK				(0x3 << 16)
+#define SCU_MISC_DAC_SOURCE_CRT			(0x1 << 16)		//00 VGA, 01: CRT, 1x: PASS-Through DVO
+#define SCU_MISC_DAC_SOURCE_MASK		(0x3 << 16)		
+#define SCU_MISC_JTAG_TO_PCIE_EN		(0x1 << 15)
+#define SCU_MISC_JTAG__M_TO_PCIE_EN		(0x1 << 14)
+#define SCU_MISC_VUART_TO_CTRL			(0x1 << 13)
+#define SCU_MISC_DIV13_EN				(0x1 << 12)
+#define SCU_MISC_Y_CLK_INVERT			(0x1 << 11)
+#define SCU_MISC_OUT_DELAY				(0x1 << 9)
+#define SCU_MISC_PCI_TO_AHB_DIS			(0x1 << 8)
+#define SCU_MISC_2D_CRT_EN				(0x1 << 7)
+#define SCU_MISC_VGA_CRT_DIS			(0x1 << 6)
+#define SCU_MISC_VGA_REG_ACCESS_EN		(0x1 << 5)
+#define SCU_MISC_D2_PLL_DIS				(0x1 << 4)
+#define SCU_MISC_DAC_DIS				(0x1 << 3)
+#define SCU_MISC_D_PLL_DIS				(0x1 << 2)
+#define SCU_MISC_OSC_CLK_OUT_PIN		(0x1 << 1)
+#define SCU_MISC_LPC_TO_SPI_DIS			(0x1 << 0)
+
+/*	AST_SCU_PCI_CONF1 : 0x30 - PCI configuration setting register#1 */
+#define SCU_PCI_DEVICE_ID(x)			(x << 16)
+#define SCU_PCI_VENDOR_ID(x)			(x)
+
+/*	AST_SCU_PCI_CONF2	0x34		PCI configuration setting register#2 */
+#define SCU_PCI_SUB_SYS_ID(x)			(x << 16)
+#define SCU_PCI_SUB_VENDOR_ID(x)		(x)
+
+/*	AST_SCU_PCI_CONF3	0x38		PCI configuration setting register#3 */
+#define SCU_PCI_CLASS_CODE(x)			(x << 8)
+#define SCU_PCI_REVISION_ID(x)			(x)
+
+/*	AST_SCU_SYS_CTRL	0x3C		System reset contrl/status register*/
+#define SCU_SYS_EXT_SOC_RESET_EN		(0x1 << 3)
+#define SCU_SYS_EXT_RESET_FLAG			(0x1 << 2)
+#define SCU_SYS_WDT_RESET_FLAG			(0x1 << 1)
+#define SCU_SYS_PWR_RESET_FLAG			(0x1 << 0)
+
+/*	AST_SCU_SOC_SCRATCH0	0x40		SOC scratch 0~31 register */
+
+
+
+
+/*	AST_SCU_SOC_SCRATCH1	0x44		SOC scratch 32~63 register */
+
+
+/*	AST_SCU_VGA0		0x40		VGA fuction handshake register */
+#define SCU_VGA_SLT_HANDSHAKE(x)		(x << 24)
+#define SCU_VGA_SLT_HANDSHAKE_MASK		(0xff << 24)
+#define SCU_VGA_CTM_DEF(x)				(x << 16)
+#define SCU_VGA_CTM_DEF_MASK			(0xff << 16)
+#define SCU_MAC0_PHY_MODE(x)			(x << 14)
+#define SCU_MAC0_GET_PHY_MODE(x)		((x >> 14) & 0x3)
+#define SCU_MAC0_PHY_MODE_MASK(x)		(0x3 << 14)
+#define SCU_MAC1_PHY_MODE(x)			(x << 12)
+#define SCU_MAC1_PHY_MODE_MASK			(0x3 << 12)
+#define SCU_MAC1_GET_PHY_MODE(x)		((x >> 12) & 0x3)
+
+#define SCU_VGA_ASPEED_DEF(x)			(x << 8)
+#define SCU_VGA_ASPEED_DEF_MASK			(0xf << 8)
+
+#define SCU_VGA_DRAM_INIT_MASK(x)		((x >> 7) & 0x1)
+
+/*	AST_SCU_VGA1		0x44		VGA fuction handshake register */
+
+
+/*	AST_SCU_MAC_CLK		0x48		MAC interface clock delay setting register */
+
+
+
+/*	AST_SCU_MISC_CTRL	0x4C		Misc. 2 Control register */
+/*	AST_SCU_VGA_SCRATCH0	0x50		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH1	0x54		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH2	0x58		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH3	0x5c		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH4	0x60		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH5	0x64		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH6	0x68		VGA Scratch register */
+/*	AST_SCU_VGA_SCRATCH7	0x6c		VGA Scratch register */
+
+/*	AST_SCU_HW_STRAP1			0x70		hardware strapping register */
+#define SCU_HW_STRAP_SW_DEFINE(x)		(x << 29)
+#define SCU_HW_STRAP_SW_DEFINE_MASK		(0x3 << 29)
+#define SCU_HW_STRAP_DRAM_SIZE			(x << 29)
+#define SCU_HW_STRAP_DRAM_SIZE_MASK		(0x3 << 29)
+
+#define VGA_64M_DRAM			0
+#define VGA_128M_DRAM			1
+#define VGA_256M_DRAM			2
+#define VGA_512M_DRAM			3
+
+#define SCU_HW_STRAP_DRAM_CONFIG		(x << 24)
+#define SCU_HW_STRAP_DRAM_CONFIG_MASK	(0x7 << 24)
+
+#define SCU_HW_STRAP_GPIOE_PT_EN		(0x1 << 22)
+#define SCU_HW_STRAP_GPIOD_PT_EN		(0x1 << 21)
+#define SCU_HW_STRAP_LPC_DEC_SUPER_IO	(0x1 << 20)
+#define SCU_HW_STRAP_ACPI_DIS			(0x1 << 19)
+
+//bit 23, 18 [1,0]
+#define SCU_HW_STRAP_SET_CLK_SOURCE(x)		((((x&0x3) >> 1)<<23)||((x&0x1) << 18))
+#define SCU_HW_STRAP_GET_CLK_SOURCE(x)		(((x>>23)&0x1<<1) | ((x>>18)&0x1))
+#define SCU_HW_STRAP_CLK_SOURCE_MASK		((0x1 << 23) | (0x1 << 18))
+
+#define CLK_25M_IN					(0x1 << 23)
+#define CLK_24M_IN					0
+#define CLK_48M_IN					1
+#define CLK_25M_IN_24M_USB_CKI		3
+#define CLK_25M_IN_48M_USB_CKI		3
+
+#define SCU_HW_STRAP_2ND_BOOT_WDT		(0x1 << 17)
+#define SCU_HW_STRAP_SUPER_IO_CONFIG	(0x1 << 16)
+#define SCU_HW_STRAP_VGA_CLASS_CODE		(0x1 << 15)
+#define SCU_HW_STRAP_LPC_RESET_PIN		(0x1 << 14)
+#define SCU_HW_STRAP_SPI_MODE(x)			(x << 12)
+#define SCU_HW_STRAP_SPI_MODE_MASK			(0x3 << 12)
+#define SPI_MODE_DIS			(0)
+#define SPI_MODE_MASTER_EN		(1)
+#define SPI_MODE_M_S_EN			(2)
+#define SPI_MODE_PS				(3)
+
+#define SCU_HW_STRAP_SET_CPU_AHB_RATIO(x)		(x << 10)
+#define SCU_HW_STRAP_GET_CPU_AHB_RATIO(x)		((x >> 10) & 3)
+#define SCU_HW_STRAP_CPU_AHB_RATIO_MASK		(0x3 << 10)
+
+
+#define CPU_AHB_RATIO_1_1		0
+#define CPU_AHB_RATIO_2_1		1
+#define CPU_AHB_RATIO_4_1		2
+#define CPU_AHB_RATIO_3_1		3
+
+#define SCU_HW_STRAP_GET_H_PLL_CLK(x)	((x >> 8 )& 0x3)
+#define SCU_HW_STRAP_H_PLL_CLK_MASK		(0x3 << 8)
+#define CPU_384MHZ		0
+#define CPU_360MHZ		1
+#define CPU_336MHZ		2
+#define CPU_408MHZ		3
+
+#define SCU_HW_STRAP_MAC1_RGMII		(0x1 << 7)
+#define SCU_HW_STRAP_MAC0_RGMII		(0x1 << 6)
+#define SCU_HW_STRAP_VGA_BIOS_ROM	(0x1 << 5)
+#define SCU_HW_STRAP_SPI_WIDTH		(0x1 << 4)
+#define SCU_HW_STRAP_VGA_SIZE_GET(x)		((x >> 2)& 0x3)
+
+#define SCU_HW_STRAP_BOOT_MODE(x)		(x)
+#define NOR_BOOT		0
+#define NAND_BOOT		1
+#define SPI_BOOT		2
+#define DIS_BOOT		3
+
+/*	AST_SCU_RAMDOM_GEN		0x74		random number generator register */
+/*	AST_SCU_RAMDOM_DATA		0x78		random number generator data output*/
+
+/*	AST_SCU_MULTI_FUNC_2	0x78 */
+
+#define MULTI_FUNC_VIDEO_RGB18			(0x1 << 2)
+#define MULTI_FUNC_VIDEO_SINGLE_EDGE	(0x1 << 0)
+
+
+
+/*	AST_SCU_REVISION_ID		0x7C		Silicon revision ID register */
+#define AST1100_A0				0x00000200
+#define AST1100_A1				0x00000201
+#define AST1100_A2				0x00000202
+#define AST1100_A3				0x00000202
+
+#define AST2050_A0				0x00000200
+#define AST2050_A1				0x00000201
+#define AST2050_A2				0x00000202
+#define AST2050_A3				0x00000202
+
+#define AST2100_A0				0x00000300
+#define AST2100_A1				0x00000301
+#define AST2100_A2				0x00000302
+#define AST2100_A3				0x00000302
+
+#define AST2200_A0				0x00000102
+#define AST2200_A1				0x00000102
+
+#define AST2300_A0				0x01000003
+#define AST2300_A1				0x01010303
+#define AST1300_A1				0x01010003
+#define AST1050_A1				0x01010203
+
+#define AST2400_A0				0x02000303
+
+
+/*	AST_SCU_FUN_PIN_CTRL1		0x80		Multi-function Pin Control#1*/
+#define SCU_FUN_PIN_UART4_RXD	(0x1 << 31)
+#define SCU_FUN_PIN_UART4_TXD	(0x1 << 30)
+#define SCU_FUN_PIN_UART4_NRTS	(0x1 << 29)
+#define SCU_FUN_PIN_UART4_NDTR	(0x1 << 28)
+#define SCU_FUN_PIN_UART4_NRI	(0x1 << 27)
+#define SCU_FUN_PIN_UART4_NDSR	(0x1 << 26)
+#define SCU_FUN_PIN_UART4_NDCD	(0x1 << 25)
+#define SCU_FUN_PIN_UART4_NCTS	(0x1 << 24)
+#define SCU_FUN_PIN_UART3_RXD	(0x1 << 23)
+#define SCU_FUN_PIN_UART3_TXD	(0x1 << 22)
+#define SCU_FUN_PIN_UART3_NRTS	(0x1 << 21)
+#define SCU_FUN_PIN_UART3_NDTR	(0x1 << 20)
+#define SCU_FUN_PIN_UART3_NRI	(0x1 << 19)
+#define SCU_FUN_PIN_UART3_NDSR	(0x1 << 18)
+#define SCU_FUN_PIN_UART3_NDCD	(0x1 << 17)
+#define SCU_FUN_PIN_UART3_NCTS	(0x1 << 16)
+
+
+
+
+#define SCU_FUN_PIN_MAC1_PHY_LINK	(0x1 << 1)
+#define SCU_FUN_PIN_MAC0_PHY_LINK	(0x1)
+
+
+/*	AST_SCU_FUN_PIN_CTRL2		0x84		Multi-function Pin Control#2*/
+#define SCU_FUN_PIN_VPIB9		(0x1 << 31)
+#define SCU_FUN_PIN_VPIB8		(0x1 << 30)
+#define SCU_FUN_PIN_VPIB7		(0x1 << 29)
+#define SCU_FUN_PIN_VPIB6		(0x1 << 28)
+#define SCU_FUN_PIN_VPIB5		(0x1 << 27)
+#define SCU_FUN_PIN_VPIB4		(0x1 << 26)
+#define SCU_FUN_PIN_VPIB3		(0x1 << 25)
+#define SCU_FUN_PIN_VPIB2		(0x1 << 24)
+#define SCU_FUN_PIN_VPIB1		(0x1 << 23)
+#define SCU_FUN_PIN_VPIB0		(0x1 << 22)
+#define SCU_FUN_PIN_VPICLK		(0x1 << 21)
+#define SCU_FUN_PIN_VPIVS		(0x1 << 20)
+#define SCU_FUN_PIN_VPIHS		(0x1 << 19)
+#define SCU_FUN_PIN_VPIODD		(0x1 << 18)
+#define SCU_FUN_PIN_VPIDE		(0x1 << 17)
+
+#define SCU_FUN_PIN_UART2_RXD	(0x1 << 31)
+#define SCU_FUN_PIN_UART2_TXD	(0x1 << 30)
+#define SCU_FUN_PIN_UART2_NRTS	(0x1 << 29)
+#define SCU_FUN_PIN_UART2_NDTR	(0x1 << 28)
+#define SCU_FUN_PIN_UART2_NRI	(0x1 << 27)
+#define SCU_FUN_PIN_UART2_NDSR	(0x1 << 26)
+#define SCU_FUN_PIN_UART2_NDCD	(0x1 << 25)
+#define SCU_FUN_PIN_UART2_NCTS	(0x1 << 24)
+#define SCU_FUN_PIN_UART1_RXD	(0x1 << 23)
+#define SCU_FUN_PIN_UART1_TXD	(0x1 << 22)
+#define SCU_FUN_PIN_UART1_NRTS	(0x1 << 21)
+#define SCU_FUN_PIN_UART1_NDTR	(0x1 << 20)
+#define SCU_FUN_PIN_UART1_NRI	(0x1 << 19)
+#define SCU_FUN_PIN_UART1_NDSR	(0x1 << 18)
+#define SCU_FUN_PIN_UART1_NDCD	(0x1 << 17)
+#define SCU_FUN_PIN_UART1_NCTS	(0x1 << 16)
+
+
+#define SCU_FUN_PIN_NAND_FLWP	(0x1 << 7)
+#define SCU_FUN_PIN_NAND_FLBUSY	(0x1 << 6)
+
+/*	AST_SCU_FUN_PIN_CTRL3		0x88		Multi-function Pin Control#3*/
+#if	defined(CONFIG_ARCH_AST1010)
+#define SCU_FUN_PIN_MAC0_MDIO	(0x1 << 23)
+#define SCU_FUN_PIN_MAC0_MDC	(0x1 << 22)
+#else
+#define SCU_FUN_PIN_MAC0_MDIO	(0x1 << 31)
+#define SCU_FUN_PIN_MAC0_MDC	(0x1 << 30)
+#define SCU_FUN_PIN_ROMA25		(0x1 << 29)
+#define SCU_FUN_PIN_ROMA24		(0x1 << 28)
+#define SCU_FUN_PIN_ROMCS4		(0x1 << 27)
+#define SCU_FUN_PIN_ROMCS3		(0x1 << 26)
+#define SCU_FUN_PIN_ROMCS2		(0x1 << 25)
+#define SCU_FUN_PIN_ROMCS1		(0x1 << 24)
+#define SCU_FUN_PIN_ROMCS(x)	(0x1 << (23+x))
+
+//Video pin
+#define SCU_FUN_PIN_VPIR9		(0x1 << 19)
+#define SCU_FUN_PIN_VPIR8		(0x1 << 18)
+#define SCU_FUN_PIN_VPIR7		(0x1 << 17)
+#define SCU_FUN_PIN_VPIR6		(0x1 << 16)
+#define SCU_FUN_PIN_VPIR5		(0x1 << 15)
+#define SCU_FUN_PIN_VPIR4		(0x1 << 14)
+#define SCU_FUN_PIN_VPIR3		(0x1 << 13)
+#define SCU_FUN_PIN_VPIR2		(0x1 << 12)
+#define SCU_FUN_PIN_VPIR1		(0x1 << 11)
+#define SCU_FUN_PIN_VPIR0		(0x1 << 10)
+#define SCU_FUN_PIN_VPIG9		(0x1 << 9)
+#define SCU_FUN_PIN_VPIG8		(0x1 << 8)
+#define SCU_FUN_PIN_VPIG7		(0x1 << 7)
+#define SCU_FUN_PIN_VPIG6		(0x1 << 6)
+#define SCU_FUN_PIN_VPIG5		(0x1 << 5)
+#define SCU_FUN_PIN_VPIG4		(0x1 << 4)
+#define SCU_FUN_PIN_VPIG3		(0x1 << 3)
+#define SCU_FUN_PIN_VPIG2		(0x1 << 2)
+#define SCU_FUN_PIN_VPIG1		(0x1 << 1)
+#define SCU_FUN_PIN_VPIG0		(0x1 << 0)
+#endif
+
+
+//pwm pin
+#define SCU_FUN_PIN_PWM_TACHO	(0)
+/*	AST_SCU_FUN_PIN_CTRL4		0x8C		Multi-function Pin Control#4*/
+#define SCU_FUN_PIN_ROMA23		(0x1 << 7)
+#define SCU_FUN_PIN_ROMA22		(0x1 << 6)
+
+#define SCU_FUN_PIN_ROMWE		(0x1 << 5)
+#define SCU_FUN_PIN_ROMOE		(0x1 << 4)
+#define SCU_FUN_PIN_ROMD7		(0x1 << 3)
+#define SCU_FUN_PIN_ROMD6		(0x1 << 2)
+#define SCU_FUN_PIN_ROMD5		(0x1 << 1)
+#define SCU_FUN_PIN_ROMD4		(0x1)
+
+/*	AST_SCU_FUN_PIN_CTRL5		0x90		Multi-function Pin Control#5*/
+#define SCU_FUN_PIN_SPICS1		(0x1 << 31)
+#define SCU_FUN_PIN_LPC_PLUS	(0x1 << 30)
+#define SCU_FUC_PIN_USB20_HOST	(0x1 << 29)
+#define SCU_FUC_PIN_USB11_PORT4	(0x1 << 28)
+#define SCU_FUC_PIN_I2C14		(0x1 << 27)
+#define SCU_FUC_PIN_I2C13		(0x1 << 26)
+#define SCU_FUC_PIN_I2C12		(0x1 << 25)
+#define SCU_FUC_PIN_I2C11		(0x1 << 24)
+#define SCU_FUC_PIN_I2C10		(0x1 << 23)
+#define SCU_FUC_PIN_I2C9		(0x1 << 22)
+#define SCU_FUC_PIN_I2C8		(0x1 << 21)
+#define SCU_FUC_PIN_I2C7		(0x1 << 20)
+#define SCU_FUC_PIN_I2C6		(0x1 << 19)
+#define SCU_FUC_PIN_I2C5		(0x1 << 18)
+#define SCU_FUC_PIN_I2C4		(0x1 << 17)
+#define SCU_FUC_PIN_I2C3		(0x1 << 16)
+#define SCU_FUC_PIN_MII2_RX_DWN_DIS		(0x1 << 15)
+#define SCU_FUC_PIN_MII2_TX_DWN_DIS		(0x1 << 14)
+#define SCU_FUC_PIN_MII1_RX_DWN_DIS		(0x1 << 13)
+#define SCU_FUC_PIN_MII1_TX_DWN_DIS		(0x1 << 12)
+
+#define SCU_FUC_PIN_MII2_TX_DRIV(x)		(x << 10)
+#define SCU_FUC_PIN_MII2_TX_DRIV_MASK	(0x3 << 10)
+#define SCU_FUC_PIN_MII1_TX_DRIV(x)		(x << 8)
+#define SCU_FUC_PIN_MII1_TX_DRIV_MASK	(0x3 << 8)
+
+#define MII_NORMAL_DRIV	0x0
+#define MII_HIGH_DRIV	0x2
+
+#define SCU_FUC_PIN_UART6		(0x1 << 7)
+#define SCU_FUC_PIN_ROM_16BIT	(0x1 << 6)
+#define SCU_FUC_PIN_DIGI_V_OUT(x)	(x << 4)
+#define SCU_FUC_PIN_DIGI_V_OUT_MASK	(0x3 << 4)
+
+#define VIDEO_DISABLE	0x0
+#define VIDEO_12BITS	0x1
+#define VIDEO_24BITS	0x2
+//#define VIDEO_DISABLE	0x3
+
+#define SCU_FUC_PIN_USB11_PORT2	(0x1 << 3)
+#define SCU_FUC_PIN_MAC1_MDIO		(0x1 << 2)
+#define SCU_FUC_PIN_SD2		(0x1 << 1)
+#define SCU_FUC_PIN_SD1		(0x1 << 0)
+
+
+/*	AST_SCU_FUN_PIN_CTRL6		0x94		Multi-function Pin Control#6*/
+#define SCU_VIDEO_OUT_MASK		(~0x3)
+
+/*	AST_SCU_WDT_RESET		0x9C		Watchdog Reset Selection */
+/*	AST_SCU_FUN_PIN_CTRL7		0xA0		Multi-function Pin Control#7*/
+/*	AST_SCU_FUN_PIN_CTRL8		0xA4		Multi-function Pin Control#8*/
+#define SCU_FUN_PIN_ROMA17		(0x1 << 31)
+#define SCU_FUN_PIN_ROMA16		(0x1 << 30)
+#define SCU_FUN_PIN_ROMA15		(0x1 << 29)
+#define SCU_FUN_PIN_ROMA14		(0x1 << 28)
+#define SCU_FUN_PIN_ROMA13		(0x1 << 27)
+#define SCU_FUN_PIN_ROMA12		(0x1 << 26)
+#define SCU_FUN_PIN_ROMA11		(0x1 << 25)
+#define SCU_FUN_PIN_ROMA10		(0x1 << 24)
+#define SCU_FUN_PIN_ROMA9		(0x1 << 23)
+#define SCU_FUN_PIN_ROMA8		(0x1 << 22)
+#define SCU_FUN_PIN_ROMA7		(0x1 << 21)
+#define SCU_FUN_PIN_ROMA6		(0x1 << 20)
+#define SCU_FUN_PIN_ROMA5		(0x1 << 19)
+#define SCU_FUN_PIN_ROMA4		(0x1 << 18)
+#define SCU_FUN_PIN_ROMA3		(0x1 << 17)
+#define SCU_FUN_PIN_ROMA2		(0x1 << 16)
+
+/*	AST_SCU_FUN_PIN_CTRL9		0xA8		Multi-function Pin Control#9*/
+#define SCU_FUN_PIN_ROMA21		(0x1 << 3)
+#define SCU_FUN_PIN_ROMA20		(0x1 << 2)
+#define SCU_FUN_PIN_ROMA19		(0x1 << 1)
+#define SCU_FUN_PIN_ROMA18		(0x1)
+
+/*	AST_SCU_PWR_SAVING_EN		0xC0		Power Saving Wakeup Enable*/
+/*	AST_SCU_PWR_SAVING_CTRL		0xC4		Power Saving Wakeup Control*/
+/*	AST_SCU_HW_STRAP2			0xD0		Haardware strapping register set 2*/
+/*	AST_SCU_COUNTER4			0xE0		SCU Free Run Counter Read Back #4*/
+/*	AST_SCU_COUNTER4_EXT		0xE4		SCU Free Run Counter Extended Read Back #4*/
+
+//CPU 2 
+/*	AST_SCU_CPU2_CTRL			0x100		CPU2 Control Register*/
+/*	AST_SCU_CPU2_BASE0_ADDR		0x104		CPU2 Base Address for Segment 0x00:0000~0x1F:FFFF*/
+/*	AST_SCU_CPU2_BASE1_ADDR		0x108		CPU2 Base Address for Segment 0x20:0000~0x3F:FFFF*/
+/*	AST_SCU_CPU2_BASE2_ADDR		0x10C		CPU2 Base Address for Segment 0x40:0000~0x5F:FFFF*/
+/*	AST_SCU_CPU2_BASE3_ADDR		0x110		CPU2 Base Address for Segment 0x60:0000~0x7F:FFFF*/
+/*	AST_SCU_CPU2_BASE4_ADDR		0x114		CPU2 Base Address for Segment 0x80:0000~0xFF:FFFF*/
+/*	AST_SCU_CPU2_CACHE_CTRL		0x118		CPU2 Cache Function Control */
+
+//
+/*	AST_SCU_UART24_REF			0x160		Generate UART 24Mhz Ref from H-PLL when CLKIN is 25Mhz */
+/*	AST_SCU_PCIE_CONFIG_SET		0x180		PCI-E Configuration Setting Control Register */
+/*	AST_SCU_BMC_MMIO_DEC		0x184		BMC MMIO Decode Setting Register */
+/*	AST_SCU_DEC_AREA1			0x188		1st relocated controller decode area location */
+/*	AST_SCU_DEC_AREA2			0x18C		2nd relocated controller decode area location */
+/*	AST_SCU_MBOX_DEC_AREA		0x190		Mailbox decode area location*/
+/*	AST_SCU_SRAM_DEC_AREA0		0x194		Shared SRAM area decode location*/
+/*	AST_SCU_SRAM_DEC_AREA1		0x198		Shared SRAM area decode location*/
+/*	AST_SCU_BMC_CLASS			0x19C		BMC device class code and revision ID */
+/*	AST_SCU_BMC_DEV_ID			0x1A4		BMC device ID */
+
+#endif
+
diff --git a/arch/arm/plat-aspeed/include/plat/regs-sdmc.h b/arch/arm/plat-aspeed/include/plat/regs-sdmc.h
new file mode 100644
index 0000000..2bcc948
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-sdmc.h
@@ -0,0 +1,31 @@
+/* arch/arm/mach-aspeed/include/mach/regs-ast1010-scu.h
+ *
+ * Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *   History      : 
+ *    1. 2012/12/29 Ryan Chen Create
+ * 
+********************************************************************************/
+#ifndef __AST_SDMC_H
+#define __AST_SDMC_H                     1
+
+/*
+ *  Register for SDMC 
+ *  */
+#define AST_SDMC_PROTECT	0x00		/*	protection key register	*/
+#define AST_SDMC_CONFIG		0x04		/*	Configuration register */
+
+
+/*	AST_SDMC_PROTECT: 0x00  - protection key register */
+#define SDMC_PROTECT_UNLOCK			0xFC600309
+
+/*	AST_SDMC_CONFIG :0x04	 - Configuration register */
+#define SDMC_CONFIG_MEM_GET(x)		(x & 0x3)
+
+
+#endif
+
diff --git a/arch/arm/plat-aspeed/include/plat/regs-smc.h b/arch/arm/plat-aspeed/include/plat/regs-smc.h
new file mode 100644
index 0000000..d4e0252
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-smc.h
@@ -0,0 +1,54 @@
+/* arch/arm/plat-aspeed/include/mach/regs-smc.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED Static memory ctrol 
+*/
+
+#ifndef __ASM_ARCH_REGS_FMC_H
+#define __ASM_ARCH_REGS_FMC_H __FILE__
+
+#define FMC_CE_TYPE				0x00
+#define FMC_CE_CTRL				0x04
+#define FMC_INTR_CTRL			0x08
+#define FMC_CE0_CTRL			0x10
+#define FMC_CE1_CTRL			0x14
+#define FMC_CE2_CTRL			0x18
+#define FMC_CE3_CTRL			0x1c
+#define FMC_CE4_CTRL			0x20
+
+#define FMC_CE0_ADDR			0x30
+#define FMC_CE1_ADDR			0x34
+#define FMC_CE2_ADDR			0x38
+#define FMC_CE3_ADDR			0x3c
+#define FMC_CE4_ADDR			0x40
+
+#define FMC_MISC_CTRL1			0x50
+#define FMC_MISC_CTRL2			0x54
+#define FMC_NAND_CTRL			0x58
+#define FMC_NAND_ECC			0x5c
+#define FMC_NAND_ECC_CK1		0x60
+#define FMC_NAND_ECC_CK2		0x64
+#define FMC_NAND_ECC_CK3		0x68
+#define FMC_NAND_ECC_GEN1		0x6c
+#define FMC_NAND_ECC_GEN2		0x70
+#define FMC_NAND_ECC_GEN3		0x74
+#define FMC_NAND_ECC_CK_R1		0x78
+#define FMC_NAND_ECC_CK_R2		0x7c
+#define FMC_DMA_CTRL			0x80
+#define FMC_DMA_FLASH_ADDR		0x84
+#define FMC_DMA_DRAM_ADDR		0x88
+#define FMC_DMA_LEN				0x8C
+#define FMC_CHECK_SUM			0x90
+#define FMC_SPI_TIMING			0x94
+
+
+
+
+
+#endif /* __ASM_ARCH_REGS_FMC_H */
diff --git a/arch/arm/plat-aspeed/include/plat/regs-spi.h b/arch/arm/plat-aspeed/include/plat/regs-spi.h
new file mode 100644
index 0000000..9b20cf8
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-spi.h
@@ -0,0 +1,51 @@
+/********************************************************************************
+* File Name     : regs-spi.h
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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 
+********************************************************************************/
+
+/* Register offsets */
+#define AST_SPI_CONFIG			0x00
+#define AST_SPI_CTRL			0x04
+#define AST_SPI_MISC			0x10
+#define AST_SPI_TIMING			0x14
+
+/* AST_SPI_CONFIG 0x00 : SPI Flash Configuration Register */
+#define SPI_CONF_CLKX2			(0x1 << 1)
+#define SPI_CONF_WRITE_EN		(0x1)
+
+/* FMC_CE0_CTRL	for SPI 0x10, 0x14, 0x18, 0x1c, 0x20 */
+#define SPI_IO_MODE(x)			(x << 28)
+#define SPI_SINGLE_BIT			0
+#define SPI_DUAL_BIT_D			2
+#define SPI_DUAL_BIT_DA			3
+#define SPI_CE_WIDTH(x)			(x << 24)
+#define SPI_CMD_DATA(x)			(x << 16)
+#define SPI_DUMMY_CMD			(1 << 15)
+#define SPI_DUMMY_HIGH			(1 << 14)
+//#define SPI_CLK_DIV				(1 << 13)		?? TODO ask....
+//#define SPI_ADDR_CYCLE			(1 << 13)		?? TODO ask....
+#define SPI_CMD_MERGE_DIS		(1 << 12)
+#define SPI_CLK_DIV(x)			(x << 8)
+#define SPI_CLK_DIV_MASK		(0xf << 8)
+
+#define SPI_DUMMY_LOW			(x << 6)
+#define SPI_LSB_FIRST_CTRL		(1 << 5)
+#define SPI_CPOL_1				(1 << 4)
+#define SPI_DUAL_DATA			(1 << 3)
+#define SPI_CE_INACTIVE			(1 << 2)
+#define SPI_CMD_MODE			(x)
+#define SPI_CMD_NOR_R_MODE		0
+#define SPI_CMD_FAST_R_MODE		1
+#define SPI_CMD_NOR_W_MODE		2
+#define SPI_CMD_USER_MODE		3
+
diff --git a/arch/arm/plat-aspeed/include/plat/regs-uart-dma.h b/arch/arm/plat-aspeed/include/plat/regs-uart-dma.h
new file mode 100644
index 0000000..2282bb1
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-uart-dma.h
@@ -0,0 +1,79 @@
+/* arch/arm/mach-aspeed/include/mach/regs-uart-dma.h
+ *
+ * Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *   History      : 
+ *    1. 2013/05/15 Ryan Chen Create
+ * 
+********************************************************************************/
+#ifndef __AST1070_UART_DMA_H
+#define __AST1070_UART_DMA_H                     1
+
+#define	UART_DMA0_TX_CTRL				0x00
+#define	UART_DMA0_TX_DESCPT				0x04
+#define	UART_DMA1_TX_CTRL				0x08
+#define	UART_DMA1_TX_DESCPT				0x0C
+#define	UART_DMA2_TX_CTRL				0x10
+#define	UART_DMA2_TX_DESCPT				0x14
+#define	UART_DMA3_TX_CTRL				0x18
+#define	UART_DMA3_TX_DESCPT				0x1C
+#define	UART_DMA0_RX_CTRL				0x20
+#define	UART_DMA0_RX_DESCPT				0x24
+#define	UART_DMA1_RX_CTRL				0x28
+#define	UART_DMA1_RX_DESCPT				0x2C
+#define	UART_DMA2_RX_CTRL				0x30
+#define	UART_DMA2_RX_DESCPT				0x34
+#define	UART_DMA3_RX_CTRL				0x38
+#define	UART_DMA3_RX_DESCPT				0x3C
+#define	UART_DMA_CTRL					0x40
+#define	UART_DMA_IER					0x44
+#define	UART_DMA_ISR					0x48
+
+/* */
+#define DMA_TRIGGER						(1 << 2)
+#define DMA_ENABLE						(1 << 0)
+
+/* UART_DMA_CTRL					0x40 */
+#define SPI_CLK_MASK					(0x1f << 16)
+#define SPI_CLK_SET(x)					((x) << 16)
+#define DMA_RX_TIMEOUT(x)				((x) << 4)
+#define DMA_BURST_LEN(x)	 			((x) << 2)
+#define DMA_BURST_MASK	 				(0x3 << 2)
+#define BURST_1							0
+#define BURST_2							1
+#define BURST_4							2
+#define BURST_8							3
+#define RXDESC_AUTO_POLLING 			(1 << 1)
+#define TXDESC_AUTO_POLLING 			(1 << 0)
+
+/* UART_DMA_IER / UART_DMA_ISR					0x44 0x48 */
+
+#define UART_DMA3_RX_INT 				(1 << 7)
+#define UART_DMA2_RX_INT 				(1 << 6)
+#define UART_DMA1_RX_INT 				(1 << 5)
+#define UART_DMA0_RX_INT 				(1 << 4)
+#define UART_DMA3_TX_INT 				(1 << 3)
+#define UART_DMA2_TX_INT 				(1 << 2)
+#define UART_DMA1_TX_INT 				(1 << 1)
+#define UART_DMA0_TX_INT 				(1 << 0)
+
+
+/* UART DESC #0 Command Register */
+#define DESC0_INT_EN					(1 << 9)
+#define DESC0_END						(1 << 8)
+#define DESC0_HW_OWN					(1 << 0)
+
+/* UART DESC #1 Base Address of Data */
+#define DESC1_LEN(x)					((x) << 16)
+#define DESC1_NEXT(x)					(x)
+
+/* UART DESC #2 Base Address of Data */
+
+/* UART DESC #3 Descriptor Status Register */
+#define DESC3_TIMEOUT_STS				(1 << 16)
+#define DESC3_GET_LEN(x)				((x) & 0xffff)
+#endif
diff --git a/arch/arm/plat-aspeed/include/plat/regs-udc11.h b/arch/arm/plat-aspeed/include/plat/regs-udc11.h
new file mode 100644
index 0000000..3b74d63
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-udc11.h
@@ -0,0 +1,98 @@
+/* arch/arm/plat-aspeed/include/mach/regs-udc11.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED UDC11 Controller
+*/
+
+#ifndef __ASM_ARCH_REGS_UDC11_H
+#define __ASM_ARCH_REGS_UDC11_H __FILE__
+
+#define	AST_UDC11_CTRL			0x00	/* Function Control and Status Register */
+#define	AST_UDC11_CONF			0x04	/* Function Configuration Setting Register */
+#define	AST_UDC11_REST			0x08	/* Endpoint Toggle Bit Reset Register */
+#define	AST_UDC11_STS			0x0C	/* USB Status Register */
+#define	AST_UDC11_IER			0x10	/* Interrupt Control Register */
+#define	AST_UDC11_ISR			0x14	/* Interrupt Status Register */
+#define AST_UDC11_EP0_CTRL		0x18	/* Endpoint 0 Control and Status Register */
+#define AST_UDC11_EP1_CTRL		0x1C	/* Endpoint 1 Control and Status Register */
+#define AST_UDC11_EP2_CTRL		0x20	/* Endpoint 2 Control and Status Register */
+#define AST_UDC11_EP0_SETUP0	0x24	/* Endpoint 0 Setup/OUT Data Buffer LOW Register */
+#define AST_UDC11_EP0_SETUP1	0x28	/* Endpoint 0 Setup/OUT Data Buffer HIGH Register */
+#define AST_UDC11_EP0_DATA0		0x2C	/* Endpoint 0 IN DATA Buffer LOW Register */
+#define AST_UDC11_EP0_DATA1		0x30	/* Endpoint 0 IN DATA Buffer HIGH Register */
+#define AST_UDC11_EP1_DATA0		0x34	/* Endpoint 1 IN DATA Buffer LOW Register */
+#define AST_UDC11_EP1_DATA1		0x38	/* Endpoint 1 IN DATA Buffer HIGH Register */
+#define AST_UDC11_EP2_DATA0		0x3C	/* Endpoint 2 IN DATA Buffer LOW Register */
+#define AST_UDC11_EP2_DATA1		0x40	/* Endpoint 2 IN DATA Buffer HIGH Register */
+
+/* AST_UDC11_CTRL			0x00		Function Control and Status Register */
+#define UDC11_CTRL_TEST_RESULT			(1 << 10)
+#define UDC11_CTRL_TEST_STS				(1 << 9)
+#define UDC11_CTRL_TEST_MODE(x)			((x) << 6)
+#define UDC11_CTRL_WKP(x)				((x) << 4)
+#define UDC11_CTRL_WKP_EN				(1 << 3)
+#define UDC11_CTRL_CLK_STOP				(1 << 2)
+#define UDC11_CTRL_LS_EN				(1 << 1)
+#define UDC11_CTRL_CONNECT_EN			(1)
+
+/* AST_UDC11_CONF			0x04		Function Configuration Setting Register */
+#define UDC11_CONF_ADDR_MASK			(0x3f << 1)
+#define UDC11_CONF_SET_ADDR(x)			(x << 1)
+#define UDC11_CONF_SET_CONF				(1)
+
+/* AST_UDC11_REST			0x08		Endpoint Toggle Bit Reset Register */
+#define UDC11_REST_EP2					(1 << 1)
+#define UDC11_REST_EP1					(1)
+
+
+/* AST_UDC11_STS			0x0C	USB Status Register */
+#define UDC11_STS_SUSPEND				(1 << 31)
+#define UDC11_STS_BUS_RST				(1 << 30)
+#define UDC11_STS_LINE_DP				(1 << 29)
+#define UDC11_STS_LINE_DN				(1 << 28)
+#define UDC11_STS_FRAM_NUM_MASK			(0x7ff << 16)
+#define UDC11_STS_GET_FRAM_NUM(x)		((x >> 16) & 0x7ff)
+#define UDC11_STS_LAST_ADDR				(0x7f << 4)
+#define UDC11_STS_LAST_EP				(0xf)
+
+/* AST_UDC11_IER			0x10		Interrupt Control Register */
+/* AST_UDC11_ISR			0x14		Interrupt Status Register */
+#define UDC11_EP0_OUT				(1 << 9)
+#define UDC11_EP0_NAK				(1 << 8)
+#define UDC11_EP2_IN_ACK			(1 << 7)
+#define UDC11_EP1_IN_ACK			(1 << 6)
+#define UDC11_EP0_IN_ACK			(1 << 5)
+#define UDC11_EP0_OUT_ACK			(1 << 4)
+#define UDC11_EP0_SETUP				(1 << 3)
+#define UDC11_SUSPEND_RESUME		(1 << 2)
+#define UDC11_SUSPEND_ENTRY			(1 << 1)
+#define UDC11_BUS_REST				(1)
+
+/* AST_UDC11_EP0_CTRL		0x18		Endpoint 0 Control and Status Register */
+/* AST_UDC11_EP1_CTRL		0x1C	Endpoint 1 Control and Status Register */
+/* AST_UDC11_EP2_CTRL		0x20		Endpoint 2 Control and Status Register */
+#define GET_EP_OUT_RX_LEN(x)		((x & 0xf) >> 8)	//only for EP0
+#define GET_EP_IN_TX_LEN(x)			((x & 0xf) >> 4)	
+#define SET_EP_IN_TX_LEN(x)			((x & 0xf) << 4)
+#define EP_OUT_BUFF_RX_RDY			(1 << 2)		//only for EP0
+#define EP_IN_BUFF_TX_RDY			(1 << 1)
+#define EP_CTRL_STALL
+
+
+
+
+
+
+
+
+
+
+
+
+#endif /* __ASM_ARCH_REGS_UDC11_H */
diff --git a/arch/arm/plat-aspeed/include/plat/regs-video.h b/arch/arm/plat-aspeed/include/plat/regs-video.h
new file mode 100644
index 0000000..ee99075
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-video.h
@@ -0,0 +1,348 @@
+/* arch/arm/mach-aspeed/include/mach/regs-video.h
+ *
+ * Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *   History      : 
+ *    1. 2012/08/15 Ryan Chen Create
+ * 
+********************************************************************************/
+#ifndef __AST_VIDEO_H
+#define __AST_VIDEO_H                     1
+
+/*
+ *  Register for VIDEO
+ *  */
+#define AST_VIDEO_PROTECT		0x000		/*	protection key register	*/
+#define AST_VIDEO_SEQ_CTRL		0x004		/*	Video Sequence Control register	*/
+#define AST_VIDEO_PASS_CTRL		0x008		/*	Video Pass 1 Control register	*/
+
+#define AST_VIDEO_DIRECT_BASE	0x00C		/*	Video Direct Frame buffer mode control Register VR008[5]=1 */
+#define AST_VIDEO_DIRECT_CTRL	0x010		/*	Video Direct Frame buffer mode control Register VR008[5]=1 */
+
+#define AST_VIDEO_TIMING_H		0x00C		/*	Video Timing Generation Setting Register */
+#define AST_VIDEO_TIMING_V		0x010		/*	Video Timing Generation Setting Register */
+#define AST_VIDEO_SCAL_FACTOR	0x014		/*	Video Scaling Factor Register */
+
+#define AST_VIDEO_SCALING0		0x018		/*	Video Scaling Filter Parameter Register #0 */
+#define AST_VIDEO_SCALING1		0x01C		/*	Video Scaling Filter Parameter Register #1 */
+#define AST_VIDEO_SCALING2		0x020		/*	Video Scaling Filter Parameter Register #2 */
+#define AST_VIDEO_SCALING3		0x024		/*	Video Scaling Filter Parameter Register #3 */
+
+#define AST_VIDEO_BCD_CTRL		0x02C		/*	Video BCD Control Register */
+#define AST_VIDEO_CAPTURE_WIN	0x030		/*	 Video Capturing Window Setting Register */
+#define AST_VIDEO_COMPRESS_WIN	0x034		/*	 Video Compression Window Setting Register */
+
+
+#define AST_VIDEO_COMPRESS_PRO	0x038		/* Video Compression Stream Buffer Processing Offset Register */
+#define AST_VIDEO_COMPRESS_READ	0x03C		/* Video Compression Stream Buffer Read Offset Register */
+
+#define AST_VIDEO_SOURCE_BUFF0	0x044		/*	Video Based Address of Video Source Buffer #1 Register */
+#define AST_VIDEO_SOURCE_SCAN_LINE	0x048		/*	Video Scan Line Offset of Video Source Buffer Register */
+#define AST_VIDEO_SOURCE_BUFF1	0x04C		/*	Video Based Address of Video Source Buffer #2 Register */
+#define AST_VIDEO_BCD_BUFF		0x050		/*	Video Base Address of BCD Flag Buffer Register */
+#define AST_VIDEO_STREAM_BUFF	0x054		/*	Video Base Address of Compressed Video Stream Buffer Register */
+#define AST_VIDEO_STREAM_SIZE	0x058		/*	Video Stream Buffer Size Register */
+
+
+#define AST_VIDEO_COMPRESS_CTRL	0x060		/* Video Compression Control Register */
+
+
+#define AST_VIDEO_DEF_HEADER	0x080		/* Video User Defined Header Parameter Setting with Compression */
+
+#define AST_VIDEO_H_DETECT_STS  0x090		/* Video Source Left/Right Edge Detection Read Back Register */
+#define AST_VIDEO_V_DETECT_STS  0x094		/* Video Source Top/Bottom Edge Detection Read Back Register */
+
+
+#define AST_VIDEO_MODE_DET_STS	0x098		/* Video Mode Detection Status Read Back Register */
+ 
+#define AST_VIDEO_MODE_DET1		0x0A4		/* Video Mode Detection Control Register 1*/
+
+
+#define AST_VIDEO_CTRL			0x300		/* Video Control Register */
+#define AST_VIDEO_INT_EN		0x304		/* Video interrupt Enable */
+#define AST_VIDEO_INT_STS		0x308		/* Video interrupt status */
+#define AST_VIDEO_MODE_DETECT	0x30C		/* Video Mode Detection Parameter Register */
+
+#define AST_VIDEO_CRC1 			0x320		/* Primary CRC Parameter Register */
+#define AST_VIDEO_CRC2 			0x324		/* Second CRC Parameter Register */
+#define AST_VIDEO_DATA_TRUNCA	0x328		/* Video Data Truncation Register */
+
+
+#define AST_VIDEO_SCRATCH_340	0x340		/* Video Scratch Remap Read Back */
+#define AST_VIDEO_SCRATCH_344	0x344		/* Video Scratch Remap Read Back */
+#define AST_VIDEO_SCRATCH_348	0x348		/* Video Scratch Remap Read Back */
+#define AST_VIDEO_SCRATCH_34C	0x34C		/* Video Scratch Remap Read Back */
+#define AST_VIDEO_SCRATCH_350	0x350		/* Video Scratch Remap Read Back */
+#define AST_VIDEO_SCRATCH_354	0x354		/* Video Scratch Remap Read Back */
+#define AST_VIDEO_SCRATCH_358	0x358		/* Video Scratch Remap Read Back */
+#define AST_VIDEO_SCRATCH_35C	0x35C		/* Video Scratch Remap Read Back */
+#define AST_VIDEO_SCRATCH_360	0x360		/* Video Scratch Remap Read Back */
+#define AST_VIDEO_SCRATCH_364	0x364		/* Video Scratch Remap Read Back */
+
+
+#define AST_VIDEO_ENCRYPT_SRAM	0x400		/* Video RC4/AES128 Encryption Key Register #0 ~ #63 */
+
+/////////////////////////////////////////////////////////////////////////////
+
+/*	AST_VIDEO_PROTECT: 0x000  - protection key register */
+#define VIDEO_PROTECT_UNLOCK			0x1A038AA8
+
+/*	AST_VIDEO_SEQ_CTRL		0x004		Video Sequence Control register	*/
+#define VIDEO_HALT_ENG_STS				(1 << 21)
+#define VIDEO_COMPRESS_BUSY				(1 << 18)
+#define VIDEO_CAPTURE_BUSY				(1 << 16)
+#define VIDEO_HALT_ENG_TRIGGER			(1 << 12)
+#define VIDEO_COMPRESS_FORMAT_MASK		(3 << 10)
+#define VIDEO_COMPRESS_FORMAT(x)		(x << 10)	// 0 YUV444
+#define YUV420		1
+#define VIDEO_COMPRESS_JPEG_CPB			(1 << 8)
+//if bit 0 : 1
+#define VIDEO_INPUT_MODE_CHG_WDT		(1 << 7)
+#define VIDEO_INSERT_FULL_COMPRESS		(1 << 6)
+#define VIDEO_AUTO_COMPRESS				(1 << 5)
+#define VIDEO_COMPRESS_TRIGGER			(1 << 4)
+#define VIDEO_CAPTURE_MULTI_FRAME		(1 << 3)
+#define VIDEO_COMPRESS_FORCE_IDLE		(1 << 2)
+#define VIDEO_CAPTURE_TIRGGER			(1 << 1)
+#define VIDEO_DETECT_TRIGGER			(1 << 0)
+
+
+#define VIDEO_HALT_ENG_RB				(1 << 21)
+#define VIDEO_HALT_ENG_RB				(1 << 21)
+#define VIDEO_HALT_ENG_RB				(1 << 21)
+#define VIDEO_HALT_ENG_RB				(1 << 21)
+#define VIDEO_HALT_ENG_RB				(1 << 21)
+#define VIDEO_HALT_ENG_RB				(1 << 21)
+
+
+/*	AST_VIDEO_PASS_CTRL			0x008		Video Pass1 Control register	*/
+//x * source frame rate / 60 
+#define VIDEO_FRAME_RATE_CTRL(x)		(x << 16)
+#define VIDEO_HSYNC_POLARITY_CTRL		(1 << 15)
+#define VIDEO_INTERLANCE_MODE			(1 << 14)
+#define VIDEO_DUAL_EDGE_MODE			(1 << 13)	//0 : Single edage
+#define VIDEO_18BIT_SINGLE_EDGE			(1 << 12)	//0: 24bits
+#define VIDEO_DVO_INPUT_DELAY_MASK		(7 << 9)	
+#define VIDEO_DVO_INPUT_DELAY(x)		(x << 9) //0 : no delay , 1: 1ns, 2: 2ns, 3:3ns 
+// if biit 5 : 0
+#define VIDEO_HW_CURSOR_DIS				(1 << 8)
+// if biit 5 : 1
+#define VIDEO_AUTO_FATCH				(1 << 8)
+#define VIDEO_CAPTURE_MODE(x)			(x << 6)
+#define YUV_MODE		1
+#define RGB_MODE		2
+#define GRAY_MODE		3
+#define VIDEO_DIRT_FATCH				(1 << 5)
+// if biit 5 : 0
+#define VIDEO_INTERNAL_DE				(1 << 4)
+#define VIDEO_EXT_ADC_ATTRIBUTE			(1 << 3)	
+
+// if biit 5 : 1
+#define VIDEO_16BPP_MODE				(1 << 4)
+#define VIDEO_16BPP_MODE_555			(1 << 3)	//0:565
+
+#define VIDEO_FROM_EXT_SOURCE			(1 << 2)	
+#define VIDEO_SO_VSYNC_POLARITY			(1 << 1)
+#define VIDEO_SO_HSYNC_POLARITY			(1 << 0)
+
+/*	AST_VIDEO_TIMING_H		0x00C		Video Timing Generation Setting Register */
+#define VIDEO_HSYNC_PIXEL_FIRST_SET(x)	((x) << 16)
+#define VIDEO_HSYNC_PIXEL_LAST_SET(x)	(x)
+
+
+/*	AST_VIDEO_DIRECT_CTRL	0x010		Video Direct Frame buffer mode control Register VR008[5]=1 */
+#define VIDEO_FETCH_TIMING(x)			((x) << 16)
+#define VIDEO_FETCH_LINE_OFFSET(x)		(x)
+
+/*	AST_VIDEO_TIMING_V		0x010		Video Timing Generation Setting Register */
+#define VIDEO_VSYNC_PIXEL_FIRST_SET(x)	((x) << 16)
+#define VIDEO_VSYNC_PIXEL_LAST_SET(x)	(x)
+
+
+/*	AST_VIDEO_SCAL_FACTOR	0x014		Video Scaling Factor Register */
+#define VIDEO_V_SCAL_FACTOR(x)			(((x) & 0xffff) << 16)
+#define VIDEO_H_SCAL_FACTOR(x)			(x & 0xffff)
+
+
+/*	AST_VIDEO_SCALING0		0x018		Video Scaling Filter Parameter Register #0 */
+/*	AST_VIDEO_SCALING1		0x01C		Video Scaling Filter Parameter Register #1 */
+/*	AST_VIDEO_SCALING2		0x020		Video Scaling Filter Parameter Register #2 */
+/*	AST_VIDEO_SCALING3		0x024		Video Scaling Filter Parameter Register #3 */
+
+
+/*	AST_VIDEO_BCD_CTRL		0x02C		Video BCD Control Register */
+#define VIDEO_ABCD_TOL(x)				(x << 24)
+#define VIDEO_BCD_TOL(x)				(x << 16)
+#define VIDEO_ABCD_CHG_EN				(1 << 1)
+#define VIDEO_BCD_CHG_EN				(1 << 0)
+
+
+
+/*	 AST_VIDEO_CAPTURE_WIN	0x030		Video Capturing Window Setting Register */
+#define VIDEO_CAPTURE_V(x)				(x & 0x7ff)
+#define VIDEO_CAPTURE_H(x)				((x & 0x7ff) << 16)
+
+/*	 AST_VIDEO_COMPRESS_WIN	0x034		Video Compression Window Setting Register */
+#define VIDEO_COMPRESS_V(x)				(x & 0x7ff)
+#define VIDEO_COMPRESS_H(x)				((x & 0x7ff) << 16)
+
+
+
+/*	AST_VIDEO_RESET :0x03c	 - system reset control register */
+
+/*	AST_VIDEO_STREAM_SIZE	0x058		Video Stream Buffer Size Register */
+#define VIDEO_STREAM_PKT_N(x)			(x << 3)
+#define STREAM_4_PKTS		0
+#define STREAM_8_PKTS		1
+#define STREAM_16_PKTS		2
+#define STREAM_32_PKTS		3
+#define STREAM_64_PKTS		4
+#define STREAM_128_PKTS		5
+
+#define VIDEO_STREAM_PKT_SIZE(x)		(x)
+#define STREAM_1KB		0
+#define STREAM_2KB		1
+#define STREAM_4KB		2
+#define STREAM_8KB		3
+#define STREAM_16KB		4
+#define STREAM_32KB		5
+#define STREAM_64KB		6
+#define STREAM_128KB	7
+
+
+
+
+
+
+
+
+/* AST_VIDEO_COMPRESS_CTRL	0x060		Video Compression Control Register */
+#define VIDEO_HQ_DCT_LUM(x)				((x) << 27)
+#define VIDEO_HQ_DCT_CHROM(x)			((x) << 22)
+#define VIDEO_DCT_HUFFMAN_ENCODE(x)		((x) << 20)
+#define VIDEO_DCT_RESET					(1 << 17)
+#define VIDEO_HQ_ENABLE					(1 << 16)
+#define VIDEO_DCT_LUM(x)				((x) << 11)
+#define VIDEO_DCT_CHROM(x)				((x) << 6)
+#define VIDEO_RC4_ENABLE				(1 << 5)
+#define VIDEO_COMPRESS_QUANTIZ_MODE		(1 << 2)
+#define VIDEO_4COLOR_VQ_ENCODE			(1 << 1)
+#define VIDEO_DCT_ONLY_ENCODE			(1 << 0)
+
+
+/* AST_VIDEO_H_DETECT_STS  0x090		Video Source Left/Right Edge Detection Read Back Register */
+#define VIDEO_DET_INTERLANCE_MODE		(1 << 31)
+#define VIDEO_GET_HSYNC_RIGHT(x)		((x & 0x0FFF0000) >> 16)
+#define VIDEO_GET_HSYNC_LEFT(x)			(x & 0xFFF)
+#define VIDEO_NO_DISPLAY_CLOCK_DET		(1 << 15)
+#define VIDEO_NO_ACT_DISPLAY_DET		(1 << 14)
+#define VIDEO_NO_HSYNC_DET				(1 << 13)
+#define VIDEO_NO_VSYNC_DET				(1 << 12)
+
+/* AST_VIDEO_V_DETECT_STS  0x094		Video Source Top/Bottom Edge Detection Read Back Register */
+#define VIDEO_GET_VSYNC_BOTTOM(x)		((x & 0x0FFF0000) >> 16)
+#define VIDEO_GET_VSYNC_TOP(x)			(x & 0xFFF)
+
+
+/* AST_VIDEO_MODE_DET_STS	0x098		Video Mode Detection Status Read Back Register */
+#define VIDEO_DET_HSYNC_RDY				(1 << 31)
+#define VIDEO_DET_VSYNC_RDY				(1 << 30)
+#define VIDEO_DET_HSYNC_POLAR			(1 << 29)
+#define VIDEO_DET_VSYNC_POLAR			(1 << 28)
+#define VIDEO_GET_VER_SCAN_LINE(x)		((x >> 16) & 0xfff)
+#define VIDEO_OUT_SYNC					(1 << 15)
+#define VIDEO_DET_VER_STABLE			(1 << 14)
+#define VIDEO_DET_HOR_STABLE			(1 << 13)
+#define VIDEO_DET_FROM_ADC				(1 << 12)
+#define VIDEO_DET_HOR_PERIOD(x)			(x & 0xfff)
+
+
+/* AST_VIDEO_MODE_DET1		0x0A4		Video Mode Detection Control Register 1*/
+#define VIDEO_DET_HSYNC_DELAY_MASK		(0xff << 16)
+#define VIDEO_DET_LONG_H_STABLE_EN		(1 << 29)
+
+
+/* AST_VIDEO_CTRL			0x300		Video Control Register */
+#define VIDEO_CTRL_CRYPTO(x)			(x << 17)
+#define VIDEO_CTRL_CRYPTO_MASK			(1 << 17)
+#define CRYPTO_RC4_MODE	0
+#define CRYPTO_AES_MODE	1
+#define VIDEO_CTRL_CRYPTO_FAST			(1 << 16)
+//15 reserved
+#define VIDEO_CTRL_RC4_VC				(1 << 14)
+#define VIDEO_CTRL_CAPTURE_MASK			(3 << 12)
+#define VIDEO_CTRL_CAPTURE_MODE(x)		(x << 12)
+#define VIDEO_CTRL_COMPRESS_MASK		(3 << 10)
+#define VIDEO_CTRL_COMPRESS_MODE(x)		(x << 10)
+#define MODE_32BPP_YUV444		0
+#define MODE_24BPP_YUV444		1
+#define MODE_16BPP_YUV422		3
+
+#define VIDEO_CTRL_RC4_TEST_MODE		(1 << 9)
+#define VIDEO_CTRL_RC4_RST				(1 << 8)
+#define VIDEO_CTRL_RC4_VIDEO_M_SEL		(1 << 7)		//video management 
+#define VIDEO_CTRL_RC4_VIDEO_2_SEL		(1 << 6)		// Video 2 
+
+#define VIDEO_CTRL_DWN_SCALING_MASK		(0x3 << 4)
+#define VIDEO_CTRL_DWN_SCALING(x)		(x << 4)
+#define DWN_V1		0x1
+#define DWN_V2		0x2
+#define DWN_VM		0x3
+
+
+
+#define VIDEO_CTRL_VSYNC_DELAY_MASK		(3 << 2)
+#define VIDEO_CTRL_VSYNC_DELAY(x)		(x << 2)
+#define NO_DELAY			0
+#define DELAY_DIV12_HSYNC	1
+#define AUTO_DELAY			2
+
+
+/* AST_VIDEO_INT_EN			0x304		Video interrupt Enable */
+/* AST_VIDEO_INT_STS		0x308		Video interrupt status */
+#define VIDEO_FRAME_COMPLETE			(1 << 5)
+#define VIDEO_MODE_DETECT_RDY			(1 << 4)
+#define VIDEO_COMPRESS_COMPLETE			(1 << 3)
+#define VIDEO_COMPRESS_PKT_COMPLETE		(1 << 2)
+#define VIDEO_CAPTURE_COMPLETE			(1 << 1)
+#define VIDEO_MODE_DETECT_WDT			(1 << 0)
+
+/* AST_VIDEO_MODE_DETECT	0x30C		Video Mode Detection Parameter Register */
+#define VIDEO_MODE_HOR_TOLER(x)			(x << 28)
+#define VIDEO_MODE_VER_TOLER(x)			(x << 24)
+#define VIDEO_MODE_HOR_STABLE(x)		(x << 20)
+#define VIDEO_MODE_VER_STABLE(x)		(x << 16)
+#define VIDEO_MODE_EDG_THROD(x)			(x << 8)
+
+#define MODEDETECTION_VERTICAL_STABLE_MAXIMUM       0x6
+#define MODEDETECTION_HORIZONTAL_STABLE_MAXIMUM     0x6
+#define MODEDETECTION_VERTICAL_STABLE_THRESHOLD     0x2
+#define MODEDETECTION_HORIZONTAL_STABLE_THRESHOLD   0x2
+
+/* AST_VIDEO_SCRATCH_34C	0x34C		Video Scratch Remap Read Back */
+#define SCRATCH_VGA_GET_REFLASH_RATE(x)			((x >> 8) & 0xf)
+#define SCRATCH_VGA_GET_COLOR_MODE(x)			((x >> 4) & 0xf)
+
+/* AST_VIDEO_SCRATCH_350	0x350		Video Scratch Remap Read Back */
+#define SCRATCH_VGA_GET_MODE_HEADER(x)			((x >> 8) & 0xff)
+#define SCRATCH_VGA_GET_NEW_COLOR_MODE(x)		((x >> 16) & 0xff)
+#define SCRATCH_VGA_GET_NEW_PIXEL_CLK(x)		((x >> 24) & 0xff)
+
+
+/* AST_VIDEO_SCRATCH_35C	0x35C		Video Scratch Remap Read Back */
+#define SCRATCH_VGA_PWR_STS_HSYNC				(1 << 31)
+#define SCRATCH_VGA_PWR_STS_VSYNC				(1 << 30)
+#define SCRATCH_VGA_ATTRIBTE_INDEX_BIT5			(1 << 29)
+#define SCRATCH_VGA_MASK_REG					(1 << 28)
+#define SCRATCH_VGA_CRT_RST						(1 << 27)
+#define SCRATCH_VGA_SCREEN_OFF					(1 << 26)
+#define SCRATCH_VGA_RESET						(1 << 25)
+#define SCRATCH_VGA_ENABLE						(1 << 24)
+
+
+#endif
+
diff --git a/arch/arm/plat-aspeed/include/plat/regs-vuart.h b/arch/arm/plat-aspeed/include/plat/regs-vuart.h
new file mode 100644
index 0000000..b4bb88a
--- /dev/null
+++ b/arch/arm/plat-aspeed/include/plat/regs-vuart.h
@@ -0,0 +1,39 @@
+/* arch/arm/plat-aspeed/include/mach/regs-iic.h
+ *
+ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
+ *		http://www.aspeedtech.com/
+ *
+ * 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.
+ *
+ * ASPEED VUART Controller
+*/
+
+#ifndef __AST_VUART_H_
+#define __AST_VUART_H_ 
+
+#define AST_VUART_CTRLA			0x20
+#define AST_VUART_CTRLB			0x24
+#define AST_VUART_ADDRL			0x28
+#define AST_VUART_ADDRH			0x2C
+#define AST_VUART_CTRLE			0x30
+#define AST_VUART_CTRLF			0x34
+#define AST_VUART_CTRLG			0x38
+#define AST_VUART_CTRLH			0x3C
+
+
+
+/* AST_VUART_CTRLA			0x20 */
+#define VUART_ENABLE				(1 << 0)
+#define VUART_SIRQ_POLARITY			(1 << 1)
+#define VUART_DISABLE_H_TX_DISCARD	(1 << 5)
+
+
+/* AST_VUART_CTRLB			0x24 */
+#define SET_SIRQ_NUM(x)			(x << 4)
+
+
+
+
+#endif 
diff --git a/arch/arm/plat-aspeed/irq.c b/arch/arm/plat-aspeed/irq.c
new file mode 100644
index 0000000..b118359
--- /dev/null
+++ b/arch/arm/plat-aspeed/irq.c
@@ -0,0 +1,136 @@
+/*
+ *  linux/arch/arm/plat-aspeed/irq.c
+ *
+ * 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/init.h>
+#include <linux/stddef.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+
+#include <plat/regs-intr.h>
+
+static void ast_mask_irq(unsigned int irq)
+{
+	int i=0;
+	u32 regVal;
+	u8 timer;
+
+#ifdef IRQ_TIMER7
+	if(((irq >= IRQ_TIMER0) && (irq <= IRQ_TIMER2)) || ((i >= IRQ_TIMER3) && (i <= IRQ_TIMER7)))
+		timer = 1;
+
+#else
+	if((irq >= IRQ_TIMER0) && (irq <= IRQ_TIMER2))
+		timer = 1;
+#endif
+	
+	if (irq > 32) {
+		i=1;
+		irq = irq - 32;
+	} else
+		i=0;
+	
+	regVal = readl(AST_INTR_DIS(i));
+	regVal |= (1 << irq);
+	writel(regVal, AST_INTR_DIS(i));
+
+	/*
+	 * clear the interrupt
+	 */
+	if(timer)
+		IRQ_EDGE_CLEAR(i,irq);	
+	
+}
+
+static void ast_unmask_irq(unsigned int irq)
+{
+	int i;
+	u32 regVal;
+
+	if (irq > 32) {
+		i=1;
+		irq = irq - 32;
+	} else
+		i=0;
+	
+	regVal = readl(AST_INTR_EN(i));
+	regVal |= (1 << irq);
+	writel(regVal, AST_INTR_EN(i));
+}
+
+static struct irq_chip ast_irq_chip = {
+	.name	= "ast_irq",
+	.ack	= ast_mask_irq,
+	.mask	= ast_mask_irq,
+	.unmask = ast_unmask_irq,
+}; 
+ 
+void __init ast_init_irq(void)
+{
+	unsigned int i;
+
+	/* VIC1 */
+	writel(0, AST_INTR_SEL(0));
+	writel(0, AST_INTR_EN(0));
+	writel(0xFFFFFFFF, AST_INTR_DIS(0));
+	writel(0xFFFFFFFF, AST_INTR_EDGE_CLR(0));
+
+#if defined(NEW_VIC)
+	writel(0, AST_INTR_SEL(1));
+	writel(0, AST_INTR_EN(1));
+	writel(0xFFFFFFFF, AST_INTR_DIS(1));
+	writel(0xFFFFFFFF, AST_INTR_EDGE_CLR(1));
+#endif
+
+	//TOTAL IRQ NUM = 
+	for (i = 0; i < AST_VIC_NUM; i++) 
+	{
+		if(i<32) {
+			if((i >= IRQ_TIMER0) && (i <= IRQ_TIMER2)) //Timer0/1/2
+				IRQ_SET_RISING_EDGE(0,i);
+			else {
+				IRQ_SET_HIGH_LEVEL(0,i);
+				IRQ_SET_LEVEL_TRIGGER(0,i);
+			}
+#ifdef IRQ_TIMER7
+		} else {
+			if((i >= IRQ_TIMER3) && (i <= IRQ_TIMER7)) //Timer3/4/5/6/7
+				IRQ_SET_RISING_EDGE(0,i-32);
+			else {
+				IRQ_SET_HIGH_LEVEL(1,i-32);
+				IRQ_SET_LEVEL_TRIGGER(1,i-32);
+			}
+#endif			
+		}
+			
+		set_irq_chip(i, &ast_irq_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+
+}
diff --git a/arch/arm/plat-aspeed/timer.c b/arch/arm/plat-aspeed/timer.c
new file mode 100644
index 0000000..079d958
--- /dev/null
+++ b/arch/arm/plat-aspeed/timer.c
@@ -0,0 +1,137 @@
+/*
+ *  timer.c
+ *
+ * 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/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+
+#include <linux/irq.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/time.h>
+#include <plat/ast-scu.h>
+
+#define ASPEED_TIMER0_VA_BASE		(IO_ADDRESS(AST_TIMER_BASE)+ASPEED_TIMER0_OFFSET)
+#define ASPEED_TIMER1_VA_BASE		(IO_ADDRESS(AST_TIMER_BASE)+ASPEED_TIMER1_OFFSET)
+#define ASPEED_TIMER2_VA_BASE		(IO_ADDRESS(AST_TIMER_BASE)+ASPEED_TIMER2_OFFSET)
+#define ASPEED_TIMERC_VA_BASE		(IO_ADDRESS(AST_TIMER_BASE)+ASPEED_TIMERRC_OFFSET)
+
+/*
+ * Returns number of ms since last clock interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long ast_gettimeoffset(void)
+{
+	volatile TimerStruct_t *timer0 = (TimerStruct_t *) ASPEED_TIMER0_VA_BASE;
+	unsigned long ticks1, ticks2;//, status;
+
+	/*
+	 * Get the current number of ticks.  Note that there is a race
+	 * condition between us reading the timer and checking for
+	 * an interrupt.  We get around this by ensuring that the
+	 * counter has not reloaded between our two reads.
+	 */
+	ticks2 = timer0->TimerValue;
+	do {
+		ticks1 = ticks2;
+//		status = readl(AST_RAW_STS(0));// __raw_readl(IO_ADDRESS(ASPEED_VIC_BASE) + ASPEED_VIC_RAW_STATUS_OFFSET);
+		ticks2 = timer0->TimerValue;
+	} while (ticks2 > ticks1);
+
+	/*
+	 * Number of ticks since last interrupt.
+	 */
+	ticks1 = TIMER_RELOAD - ticks2;
+
+	/*
+	 * Interrupt pending?  If so, we've reloaded once already.
+	 */
+//	if (status & (1 << IRQ_TIMER0))
+//		ticks1 += TIMER_RELOAD;
+
+	/*
+	 * Convert the ticks to usecs
+	 */
+	return TICKS2USECS(ticks1);
+}
+
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t 
+ast_timer_interrupt(int irq, void *dev_id)
+{
+
+//	write_seqlock(&xtime_lock);
+
+	/*
+	 * clear the interrupt in Irq.c
+	 */
+//	IRQ_EDGE_CLEAR(0,IRQ_TIMER0);
+
+	timer_tick();
+
+
+//	write_sequnlock(&xtime_lock);
+
+	return IRQ_HANDLED;	
+}
+
+static struct irqaction ast_timer_irq = {
+	.name		= "ast timer",
+	.flags		= IRQF_DISABLED |  IRQF_TIMER,
+	.handler	= ast_timer_interrupt,
+};
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static void __init ast_setup_timer(void)
+{
+	volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *) ASPEED_TIMER0_VA_BASE;
+    volatile __u32         *timerc = (volatile __u32*) ASPEED_TIMERC_VA_BASE;
+
+	/*
+	 * Initialise to a known state (all timers off)
+	 */
+        *timerc = 0;
+
+	timer0->TimerLoad    = TIMER_RELOAD - 1;
+	timer0->TimerValue   = TIMER_RELOAD - 1;
+	*timerc              = TIMER0_ENABLE | TIMER0_RefExt;
+
+	/* 
+	 * Make irqs happen for the system timer
+	 */
+	ast_scu_show_system_info();
+	
+	setup_irq(IRQ_TIMER0, &ast_timer_irq);
+
+}
+
+struct sys_timer ast_timer = {
+	.init		= ast_setup_timer,
+//	.offset		= ast_gettimeoffset,
+};
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 43aa202..d2bf539 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1899,3 +1899,4 @@ rut100			MACH_RUT100		RUT100			1908
 asusp535		MACH_ASUSP535		ASUSP535		1909
 htcraphael		MACH_HTCRAPHAEL		HTCRAPHAEL		1910
 sygdg1			MACH_SYGDG1		SYGDG1			1911
+aspeed			MACH_ASPEED		ASPEED			8888
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 43d6ba8..a714292 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -665,6 +665,7 @@ config IBM_BSR
 	  between several cores on a system
 
 source "drivers/char/ipmi/Kconfig"
+source "drivers/char/aspeed/Kconfig"
 
 config DS1620
 	tristate "NetWinder thermometer support"
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 438f713..ee197cb 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_TOSHIBA)		+= toshiba.o
 obj-$(CONFIG_I8K)		+= i8k.o
 obj-$(CONFIG_DS1620)		+= ds1620.o
 obj-$(CONFIG_HW_RANDOM)		+= hw_random/
+obj-$(CONFIG_AST_MISC)		+= aspeed/
 obj-$(CONFIG_PPDEV)		+= ppdev.o
 obj-$(CONFIG_NWBUTTON)		+= nwbutton.o
 obj-$(CONFIG_NWFLASH)		+= nwflash.o
diff --git a/drivers/char/aspeed/Kconfig b/drivers/char/aspeed/Kconfig
new file mode 100644
index 0000000..7aee8d3
--- /dev/null
+++ b/drivers/char/aspeed/Kconfig
@@ -0,0 +1,52 @@
+#
+# MISC configuration for ASPEED SOCs
+#
+
+if ARCH_ASPEED
+menuconfig AST_MISC
+	tristate 'MISC drivers for ASPEED SOCs'
+	help
+	  We can select misc drivers for ASPEED SOC in this sub-function.
+
+if AST_MISC
+config AST_VIDEO
+	tristate "ASPEED Video Engine driver"
+	default n
+	help
+	  Driver for AST Video Engine 
+
+config ADC_CAT9883
+	tristate "CAT 9883 ADC driver"
+	default n
+	help
+	  Driver for CAT 9883
+
+config AST_SPI_BIOS
+	tristate "ASPEED SPI BIOS flash register"
+	default n
+	help 
+	  Driver for SPI BIOS flash register 
+
+config AST_PECI
+	tristate "ASPEED PECI Controller"
+	default n
+	help
+	  Driver for PECI Controller
+
+config AST_KCS
+	tristate 'ASPEED KCS support'
+	help
+	  Support for the KCS channels on the ASPEED chips,
+	  providing /dev/kcs0, 1 and 2 (note, some machines may not
+	  provide all of these ports, depending on how the serial port
+	  pins are configured.
+
+config AST_GPIO
+	tristate "ASPEED GPIO Controller"
+	default n
+	help
+	  Driver for GPIO Controller included in ASPEED SOCs.
+
+endif	# CONFIG_AST_MISC
+endif	# CONFIG_AST
+
diff --git a/drivers/char/aspeed/Makefile b/drivers/char/aspeed/Makefile
new file mode 100644
index 0000000..517b2b7
--- /dev/null
+++ b/drivers/char/aspeed/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the ASPEED drivers.
+#
+
+obj-$(CONFIG_AST_VIDEO)		+= ast_video.o
+obj-$(CONFIG_ADC_CAT9883)	+= adc_cat9883.o
+obj-$(CONFIG_AST_KCS)		+= ast_kcs.o
+obj-$(CONFIG_AST_GPIO) 		+= ast_gpio.o
+obj-$(CONFIG_AST_PECI)		+= ast_peci.o
diff --git a/drivers/char/aspeed/ast_peci.c b/drivers/char/aspeed/ast_peci.c
new file mode 100644
index 0000000..1f7cae3
--- /dev/null
+++ b/drivers/char/aspeed/ast_peci.c
@@ -0,0 +1,508 @@
+/********************************************************************************
+* File Name     : ast_peci.c
+* Author         : Ryan Chen
+* Description   : AST PECI Controller
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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 
+*
+*   Version      : 1.0
+*   History      : 
+*      1. 2013/01/30 Ryan Chen create this file 
+*    
+********************************************************************************/
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <asm/uaccess.h>
+
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/miscdevice.h>
+#ifdef CONFIG_COLDFIRE
+#include <asm/arch/regs-peci.h>
+#else
+#include <plat/regs-peci.h>
+#endif
+
+//#define CONFIG_AST_PECI_DEBUG
+
+#ifdef CONFIG_AST_PECI_DEBUG
+	#define PECI_DBG(fmt, args...) printk("%s(): " fmt, __FUNCTION__, ## args)
+#else
+	#define PECI_DBG(fmt, args...)
+#endif
+
+/***********************************************************************/
+struct timing_negotiation {
+	u8		msg_timing;
+	u8		addr_timing;	
+};
+
+struct xfer_msg {
+	u8		client_addr;
+	u8		tx_len;
+	u8		rx_len;
+	u8		tx_fcs;
+	u8		rx_fcs;
+	u8		fcs_en;
+	u8		sw_fcs;
+	u8		*tx_buf;
+	u8		*rx_buf;
+	u32		sts;
+};
+
+#define PECI_DEVICE      "/dev/ast-peci"
+
+//IOCTL ..
+#define PECIIOC_BASE       'P'
+
+#define AST_PECI_IOCRTIMING		_IOR(PECIIOC_BASE, 0, struct timing_negotiation*)
+#define AST_PECI_IOCWTIMING		_IOW(PECIIOC_BASE, 1, struct timing_negotiation*)
+#define AST_PECI_IOCXFER		_IOWR(PECIIOC_BASE, 2, struct xfer_msg*)
+
+
+/***********************************************************************/
+
+static struct ast_peci_data {
+	struct device			*misc_dev;
+	void __iomem			*reg_base;			/* virtual */
+	int 					irq;				//PECI IRQ number 
+	int 				open_count;	
+	struct completion		xfer_complete;	
+	u32					sts;
+	struct mutex lock;	
+} ast_peci;
+
+static inline void
+ast_peci_write(u32 val, u32 reg)
+{
+	PECI_DBG("write offset: %x, val: %x \n",reg,val);
+	writel(val, ast_peci.reg_base + reg);
+}
+
+static inline u32
+ast_peci_read(u32 reg)
+{
+	u32 val = readl(ast_peci.reg_base + reg);
+	PECI_DBG("read offset: %x, val: %x \n",reg,val);
+	return val;
+}
+
+static long ast_peci_ioctl(struct file *fp,
+			     unsigned int cmd, unsigned long arg)
+{
+	long ret = 0;
+	void __user *argp = (void __user *)arg;
+	struct xfer_msg msg;
+	struct timing_negotiation tim_ng;
+	u32	peci_head;
+	int i=0;
+	u32 *tx_buf0 = (u32 *) (ast_peci.reg_base + AST_PECI_W_DATA0);
+	u32 *tx_buf1 = (u32 *) (ast_peci.reg_base + AST_PECI_W_DATA4);
+	u32 *rx_buf0 = (u32 *) (ast_peci.reg_base + AST_PECI_R_DATA0);
+	u32 *rx_buf1 = (u32 *) (ast_peci.reg_base + AST_PECI_R_DATA4);
+	u32 rx_data;
+
+	PECI_DBG("ast_peci_ioctl cmd %x \n", cmd);
+
+	switch(cmd) {
+		case AST_PECI_IOCRTIMING:
+			tim_ng.msg_timing = PECI_TIMING_MESSAGE_GET(ast_peci_read(AST_PECI_TIMING));
+			tim_ng.addr_timing = PECI_TIMING_ADDRESS_GET(ast_peci_read(AST_PECI_TIMING)); 
+			if (copy_to_user(argp, &tim_ng, sizeof(struct timing_negotiation)))
+				ret = -EFAULT;
+			break;
+			
+		case AST_PECI_IOCWTIMING:	
+			if (copy_from_user(&tim_ng, argp, sizeof(struct timing_negotiation))) {
+				ret = -EFAULT;
+			} else {
+				ast_peci_write(PECI_TIMING_MESSAGE(tim_ng.msg_timing) | 
+							PECI_TIMING_ADDRESS(tim_ng.addr_timing), AST_PECI_TIMING);
+			}
+			break;
+			
+		case AST_PECI_IOCXFER:
+			//Check cmd operation sts 
+			while(ast_peci_read(AST_PECI_CMD) & PECI_CMD_FIRE) {
+				printk("wait for free \n");
+			};
+
+			if (copy_from_user(&msg, argp, sizeof(struct xfer_msg))) {
+				ret = -EFAULT;
+				break;
+			}
+
+#ifdef CONFIG_AST_PECI_DEBUG
+			printk("fcs_en %d, client_addr %x, tx_len %d, rx_len %d",msg.fcs_en ,msg.client_addr, msg.tx_len, msg.rx_len);
+			printk("\ntx_buf : ");
+			for(i = 0;i< msg.tx_len; i++)
+				printk(" %x ",msg.tx_buf[i]);
+			printk("\n");
+#endif
+
+			if(msg.fcs_en)
+				peci_head = PECI_TAGET_ADDR(msg.client_addr) | 
+							PECI_WRITE_LEN(msg.tx_len) | 
+							PECI_READ_LEN(msg.rx_len) | PECI_AW_FCS_EN;
+			else
+				peci_head = PECI_TAGET_ADDR(msg.client_addr) | 
+							PECI_WRITE_LEN(msg.tx_len) | 
+							PECI_READ_LEN(msg.rx_len);
+				
+				
+			ast_peci_write(peci_head, AST_PECI_CMD_CTRL);		
+
+			for(i = 0; i < msg.tx_len; i++) {
+				if(i < 16) {
+					if(i%4 == 0)
+						tx_buf0[i/4] = 0;
+					tx_buf0[i/4] |= (msg.tx_buf[i] << ((i%4)*8)) ;
+				} else {
+					if(i%4 == 0)
+						tx_buf1[i/4] = 0;
+					tx_buf1[i/4] |= (msg.tx_buf[i] << ((i%4)*8)) ;
+				}
+			}
+
+#ifdef CONFIG_AST_PECI_DEBUG
+			printk("\nWD \n ");
+			ast_peci_read(AST_PECI_W_DATA0);
+			ast_peci_read(AST_PECI_W_DATA1);
+			ast_peci_read(AST_PECI_W_DATA2);
+			ast_peci_read(AST_PECI_W_DATA3);
+			ast_peci_read(AST_PECI_W_DATA4);
+			ast_peci_read(AST_PECI_W_DATA5);
+			ast_peci_read(AST_PECI_W_DATA6);
+			ast_peci_read(AST_PECI_W_DATA7);
+#endif
+			init_completion(&ast_peci.xfer_complete);
+			//Fire Command
+			ast_peci_write(PECI_CMD_FIRE, AST_PECI_CMD);	
+			
+			
+			ret = wait_for_completion_interruptible_timeout(&ast_peci.xfer_complete, 30*HZ);
+			
+			if (ret == 0)
+				printk("peci controller timed out\n");
+
+			for(i = 0; i < msg.rx_len; i++) {
+				if(i < 16) {
+					switch(i%4) {
+						case 0:
+							rx_data = rx_buf0[i/4];
+							
+							msg.rx_buf[i] = rx_data & 0xff; 
+							break;
+						case 1:
+							msg.rx_buf[i] = (rx_data & 0xff00) >> 8; 
+							break;
+						case 2:
+							msg.rx_buf[i] = (rx_data & 0xff0000) >> 16; 
+							break;
+						case 3:
+							msg.rx_buf[i] = (rx_data & 0xff000000) >> 24; 
+							break;
+
+					}
+				} else {
+					switch(i%4) {
+						case 0:
+							rx_data = rx_buf1[i/4];
+							msg.rx_buf[i] = rx_data & 0xff; 
+							break;
+						case 1:
+							msg.rx_buf[i] = (rx_data & 0xff00) >> 8; 
+							break;
+						case 2:
+							msg.rx_buf[i] = (rx_data & 0xff0000) >> 16; 
+							break;
+						case 3:
+							msg.rx_buf[i] = (rx_data & 0xff000000) >> 24; 
+							break;
+
+					}
+				}
+			}
+#ifdef CONFIG_AST_PECI_DEBUG
+			printk("\nRD \n");
+			ast_peci_read(AST_PECI_R_DATA0);
+			ast_peci_read(AST_PECI_R_DATA1);
+			ast_peci_read(AST_PECI_R_DATA2);
+			ast_peci_read(AST_PECI_R_DATA3);			
+			ast_peci_read(AST_PECI_R_DATA4);
+			ast_peci_read(AST_PECI_R_DATA5);
+			ast_peci_read(AST_PECI_R_DATA6);
+			ast_peci_read(AST_PECI_R_DATA7);			
+
+			printk("rx_buf : ");
+			for(i = 0;i< msg.rx_len; i++)
+				printk("%x ",msg.rx_buf[i]);
+			printk("\n");
+#endif		
+			msg.sts = ast_peci.sts;
+			msg.rx_fcs = PECI_CAPTURE_READ_FCS(ast_peci_read(AST_PECI_CAP_FCS));
+			if (copy_to_user(argp, &msg, sizeof(struct xfer_msg)))
+				ret = -EFAULT;
+			
+			break;
+		default:			
+			printk("ast_peci_ioctl command fail\n");
+			ret = -ENOTTY;
+			break;			
+	}
+
+	return ret;
+}
+
+static int ast_peci_open(struct inode *inode, struct file *file)
+{
+	PECI_DBG("ast_peci_open\n");
+
+
+	/* Flush input queue on first open */
+	if (ast_peci.open_count)
+		return -1;
+	
+	ast_peci.open_count++;
+
+
+	return 0;
+}
+
+static int ast_peci_release(struct inode *inode, struct file *file)
+{
+	PECI_DBG("ast_peci_release\n");
+	ast_peci.open_count--;
+	
+	return 0;	
+}
+
+static irqreturn_t ast_peci_handler(int this_irq, void *dev_id)
+{
+	ast_peci.sts = (0x1f & ast_peci_read(AST_PECI_INT_STS));
+	
+	switch(ast_peci.sts) {
+		case PECI_INT_TIMEOUT:
+			printk("PECI_INT_TIMEOUT \n");
+			ast_peci_write(PECI_INT_TIMEOUT, AST_PECI_INT_STS);
+			break;
+		case PECI_INT_CONNECT:
+			printk("PECI_INT_CONNECT \n");
+			ast_peci_write(PECI_INT_CONNECT, AST_PECI_INT_STS);			
+			break;
+		case PECI_INT_W_FCS_BAD:
+			printk("PECI_INT_W_FCS_BAD \n");
+			ast_peci_write(PECI_INT_W_FCS_BAD, AST_PECI_INT_STS);						
+			break;
+		case PECI_INT_W_FCS_ABORT:
+			printk("PECI_INT_W_FCS_ABORT \n");
+			ast_peci_write(PECI_INT_W_FCS_ABORT, AST_PECI_INT_STS);									
+			break;
+		case PECI_INT_CMD_DONE:
+			printk("PECI_INT_CMD_DONE \n");
+			ast_peci_write(PECI_INT_CMD_DONE, AST_PECI_INT_STS);	
+			ast_peci_write(0, AST_PECI_CMD);
+			break;
+		default:
+			printk("no one handle .... \n");
+			break;
+		
+	}
+
+	complete(&ast_peci.xfer_complete);
+	
+	return IRQ_HANDLED;
+
+}
+
+static void ast_peci_ctrl_init(void)
+{
+	//PECI Timing Setting : should 4 times of peci clk period 64 = 16 * 4 ??
+	ast_peci_write(PECI_TIMING_MESSAGE(64) | PECI_TIMING_ADDRESS(64), AST_PECI_TIMING);
+
+
+	//PECI Programmable AWFCS
+	//ast_peci_write(ast_peci, PECI_PROGRAM_AW_FCS, AST_PECI_EXP_FCS);
+
+	//TODO ..... 
+	//Clear Interrupt
+	ast_peci_write(PECI_INT_TIMEOUT | PECI_INT_CONNECT | 
+					PECI_INT_W_FCS_BAD | PECI_INT_W_FCS_ABORT |
+					PECI_INT_CMD_DONE, AST_PECI_INT_STS);
+	
+	//PECI Negotiation Selection , interrupt enable 
+	//Set nego mode :  1st bit of addr negotiation 
+	ast_peci_write(PECI_INT_TIMEOUT | PECI_INT_CONNECT | 
+					PECI_INT_W_FCS_BAD | PECI_INT_W_FCS_ABORT |
+					PECI_INT_CMD_DONE, AST_PECI_INT_CTRL);
+
+	//PECI Spec wide speed rangs [2kbps~2Mbps]
+	//Sampling 8/16, READ mode : Point Sampling , CLK source : 24Mhz , DIV by 8 : 3 --> CLK is 3Mhz
+	//PECI CTRL Enable 
+
+	ast_peci_write(PECI_CTRL_SAMPLING(8) | PECI_CTRL_CLK_DIV(3) | 
+					PECI_CTRL_PECI_EN | 
+					PECI_CTRL_PECI_CLK_EN, AST_PECI_CTRL);	
+}
+
+static const struct file_operations ast_peci_fops = {
+        .owner =        	THIS_MODULE,
+        .llseek =       	no_llseek,
+        .unlocked_ioctl =	ast_peci_ioctl,
+        .open =         	ast_peci_open,
+        .release =      	ast_peci_release,
+};
+
+struct miscdevice ast_peci_misc = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "ast-peci",
+	.fops = &ast_peci_fops,
+};
+
+static int ast_peci_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	int ret=0;
+
+
+	PECI_DBG("ast_peci_probe\n");	
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (NULL == res) {
+		dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
+		ret = -ENOENT;
+		goto out;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res), res->name)) {
+		dev_err(&pdev->dev, "cannot reserved region\n");
+		ret = -ENXIO;
+		goto out;
+	}
+
+	ast_peci.reg_base = ioremap(res->start, resource_size(res));
+	if (!ast_peci.reg_base) {
+		ret = -EIO;
+		goto out_region;
+	}
+
+	ast_peci.irq = platform_get_irq(pdev, 0);
+	if (ast_peci.irq < 0) {
+		dev_err(&pdev->dev, "no irq specified\n");
+		ret = -ENOENT;
+		goto out_region;
+	}
+
+	ret = request_irq(ast_peci.irq, ast_peci_handler, IRQF_SHARED,
+			  "ast-peci", &ast_peci);
+	
+	if (ret) {
+		printk(KERN_INFO "PECI: Failed request irq %d\n", ast_peci.irq);
+		goto out_region;
+	}
+	
+	ret = misc_register(&ast_peci_misc);
+	if (ret){		
+		printk(KERN_ERR "PECI : failed to request interrupt\n");
+		goto out_irq;
+	}
+
+	ast_peci_ctrl_init();
+	
+	printk(KERN_INFO "ast_peci: driver successfully loaded.\n");
+
+	return 0;
+
+
+out_irq:
+	free_irq(ast_peci.irq, NULL);
+out_region:
+	release_mem_region(res->start, res->end - res->start + 1);
+out:
+	printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
+	return ret;
+}
+
+static int ast_peci_remove(struct platform_device *pdev)
+{
+	struct resource *res;
+
+	PECI_DBG("ast_peci_remove\n");
+
+	misc_deregister(&ast_peci_misc);
+
+	free_irq(ast_peci.irq, &ast_peci);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	iounmap(ast_peci.reg_base);
+
+	release_mem_region(res->start, res->end - res->start + 1);
+
+	return 0;	
+}
+
+#ifdef CONFIG_PM
+static int 
+ast_peci_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	printk("ast_peci_suspend : TODO \n");
+	return 0;
+}
+
+static int 
+ast_peci_resume(struct platform_device *pdev)
+{
+	ast_peci_ctrl_init();
+	return 0;
+}
+
+#else
+#define ast_peci_suspend        NULL
+#define ast_peci_resume         NULL
+#endif
+
+static struct platform_driver ast_peci_driver = {
+	.probe			= ast_peci_probe,
+	.remove 		= __devexit_p(ast_peci_remove),
+    .suspend        = ast_peci_suspend,
+    .resume         = ast_peci_resume,
+    .driver         = {
+            .name   = "ast_peci",
+            .owner  = THIS_MODULE,
+    },
+};
+
+static int __init 
+ast_peci_init(void)
+{
+	return platform_driver_register(&ast_peci_driver);
+}
+
+static void __exit 
+ast_peci_exit(void)
+{
+	platform_driver_unregister(&ast_peci_driver);
+}
+
+module_init(ast_peci_init);
+module_exit(ast_peci_exit);
+
+MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
+MODULE_DESCRIPTION("PECI driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index a4424c8..1963ba6 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -265,9 +265,13 @@ static ssize_t gpio_value_store(struct device *dev,
 
 	if (!test_bit(FLAG_EXPORT, &desc->flags))
 		status = -EIO;
-	else if (!test_bit(FLAG_IS_OUT, &desc->flags))
+#if 0	//Ryan Modify for AST GPIO Feature
+	else if (!test_bit(FLAG_IS_OUT, &desc->flags)) {
 		status = -EPERM;
+	} else {
+#else
 	else {
+#endif	
 		long		value;
 
 		status = strict_strtol(buf, 0, &value);
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index c709e82..681782b 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -854,6 +854,22 @@ config SENSORS_LIS3LV02D
 	  This driver can also be built as a module.  If so, the module
 	  will be called lis3lv02d.
 
+config SENSORS_AST_ADC
+	tristate "ASPEED ADC Controller Driver"
+        depends on ARCH_ASPEED
+	default n
+	help
+          This driver provides support for the ASPEED ADC
+          Controller, which provides an Voltage Sensor.
+
+config SENSORS_AST_PWM_FAN
+        tristate "ASPEED PWM & FAN Tacho Controller Driver"
+        depends on ARCH_ASPEED
+        default n
+        help
+          This driver provides support for the ASPEED PWM & FAN Tacho
+          Controller, which provides an Sensor, fan control.
+
 config SENSORS_APPLESMC
 	tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
 	depends on INPUT && X86
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 58fc5be..5629727 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -29,6 +29,8 @@ obj-$(CONFIG_SENSORS_ADT7462)	+= adt7462.o
 obj-$(CONFIG_SENSORS_ADT7470)	+= adt7470.o
 obj-$(CONFIG_SENSORS_ADT7473)	+= adt7473.o
 obj-$(CONFIG_SENSORS_APPLESMC)	+= applesmc.o
+obj-$(CONFIG_SENSORS_AST_ADC)	+= ast_adc.o
+obj-$(CONFIG_SENSORS_AST_PWM_FAN)	+= ast_pwm_fan.o
 obj-$(CONFIG_SENSORS_AMS)	+= ams/
 obj-$(CONFIG_SENSORS_ATXP1)	+= atxp1.o
 obj-$(CONFIG_SENSORS_CORETEMP)	+= coretemp.o
diff --git a/drivers/hwmon/ast_adc.c b/drivers/hwmon/ast_adc.c
new file mode 100644
index 0000000..0969e39
--- /dev/null
+++ b/drivers/hwmon/ast_adc.c
@@ -0,0 +1,734 @@
+/*
+ *  ast_adc.c
+ *
+ *  ASPEED ADC controller driver
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *  History:
+ *    2012.11.26: Initial version [Ryan Chen]
+ */
+
+/* attr ADC sysfs 0~max adc channel 
+*	 0 - show/store enable
+*	 3 - show value
+*	 1 - show/store alarm_en set enable 
+*	 2 - show alarm   get statuse
+*	 4 - show/store upper
+*	 5 - show/store lower  */
+
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/mutex.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon.h>
+#include <linux/workqueue.h>
+#include <linux/sysfs.h>
+#include <linux/err.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <plat/regs-adc.h>
+#include <plat/ast-scu.h>
+
+
+#define REST_DESIGN		0
+
+struct adc_vcc_ref_data {
+	int v2;
+	int r1;
+	int r2;	
+};
+
+static struct adc_vcc_ref_data adc_vcc_ref[5] = {
+	[0] = {
+		.v2 = 0,
+		.r1 = 5600,
+		.r2 = 1000,
+	},
+	[1] = {
+		.v2 = -12,
+		.r1 = 1000,
+		.r2 = 10000,
+	},
+	[2] = {
+		.v2 = 0,
+		.r1 = 1800,
+		.r2 = 1000,
+	},
+	[3] = {
+		.v2 = -5,
+		.r1 = 2200,
+		.r2 = 10000,
+	},
+	[4] = {
+		.v2 = 0,
+		.r1 = 56000,
+		.r2 = 1000,
+	},
+};
+
+struct ast_adc_data {
+	struct device			*hwmon_dev;
+	void __iomem			*reg_base;			/* virtual */
+	int 					irq;				//ADC IRQ number 
+	int						compen_value;		//Compensating value
+};
+
+struct ast_adc_data *ast_adc;
+
+static u8 ast_get_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch);
+
+
+static inline void
+ast_adc_write(struct ast_adc_data *ast_adc, u32 val, u32 reg)
+{
+//	printk("write offset: %x, val: %x \n",reg,val);
+	writel(val, ast_adc->reg_base+ reg);
+}
+
+static inline u32
+ast_adc_read(struct ast_adc_data *ast_adc, u32 reg)
+{
+	u32 val = readl(ast_adc->reg_base + reg);
+//	printk("read offset: %x, val: %x \n",reg,val);
+	return val;
+}
+
+static void ast_adc_ctrl_init(void)
+{
+	u32 pclk;
+	ast_adc_write(ast_adc, AST_ADC_CTRL_COMPEN | AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+
+	//Set wait a sensing cycle t (s) = 1000 * 12 * (1/PCLK) * 2 * (ADC0c[31:17] + 1) * (ADC0c[9:0] +1)
+	//ex : pclk = 48Mhz , ADC0c[31:17] = 0,  ADC0c[9:0] = 0x40 : 64,  ADC0c[31:17] = 0x3e7 : 999 
+	// --> 0.0325s	= 12 * 2 * (0x3e7 + 1) *(64+1) / 48000000
+	// --> 0.0005s	= 12 * 2 * (0x3e7 + 1) / 48000000	
+	
+	pclk = ast_get_pclk();
+
+#if defined(CONFIG_ARCH_AST2300)
+	ast_adc_write(ast_adc, 0x3e7, AST_ADC_CLK); 
+
+	ast_adc_write(ast_adc, AST_ADC_CTRL_CH12_EN | AST_ADC_CTRL_COMPEN_CLR| ast_adc_read(ast_adc, AST_ADC_CTRL), AST_ADC_CTRL);
+
+	mdelay(50);
+
+	//compensating value = 0x200 - ADC10[9:0]
+	if(ast_adc_read(ast_adc, AST_ADC_CH12_13) & (0x1 << 8))
+		ast_adc->compen_value = 0x200 - (ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_L_CH_MASK);
+	else
+		ast_adc->compen_value = 0 - (ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_L_CH_MASK);
+	
+	printk("compensating value %d \n",ast_adc->compen_value);
+	
+#elif defined(CONFIG_ARCH_AST2400)
+
+	//For AST2400 A0 workaround  ... ADC0c = 1 ;
+//	ast_adc_write(ast_adc, 1, AST_ADC_CLK);
+//	ast_adc_write(ast_adc, (0x3e7<< 17) | 0x40, AST_ADC_CLK);
+	ast_adc_write(ast_adc, 0x40, AST_ADC_CLK);
+	
+	ast_adc_write(ast_adc, AST_ADC_CTRL_CH0_EN | AST_ADC_CTRL_COMPEN | AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+
+	ast_adc_read(ast_adc, AST_ADC_CTRL);
+
+	mdelay(1);
+
+	//compensating value = 0x200 - ADC10[9:0]
+	ast_adc->compen_value = 0x200 - (ast_adc_read(ast_adc, AST_ADC_CH0_1) & AST_ADC_L_CH_MASK);
+	printk("compensating value %d \n",ast_adc->compen_value);
+
+#elif defined(CONFIG_ARCH_AST2500)
+//	TODO ... 
+//	scu read trim 
+//	write trim 0xc4 [3:0]
+	
+	ast_adc_write(ast_adc, 0x40, AST_ADC_CLK);
+	
+	ast_adc_write(ast_adc, AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+
+    while(!ast_adc_read(ast_adc, AST_ADC_CTRL) & 0x100);
+
+	ast_adc_write(ast_adc, AST_ADC_CTRL_COMPEN  | AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+
+	while(ast_adc_read(ast_adc, AST_ADC_CTRL) & AST_ADC_CTRL_COMPEN);
+	
+	//compensating value = 0x200 - ADC10[9:0]
+	ast_adc->compen_value = 0x200 - ((ast_adc_read(ast_adc, AST_ADC_TRIM) >> 16) & 0x3ff);
+	printk("compensating value %d \n",ast_adc->compen_value);
+	
+#else
+#err "No define for ADC "
+#endif
+
+	ast_adc_write(ast_adc, AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+	
+}
+
+static u16
+ast_get_adc_hyster_lower(struct ast_adc_data *ast_adc, u8 adc_ch)
+{
+    u16 tmp=0;
+	tmp = ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & AST_ADC_L_BOUND;
+
+//	printk("read val = %d \n",tmp);
+
+	return tmp;
+
+}
+
+static void
+ast_set_adc_hyster_lower(struct ast_adc_data *ast_adc, u8 adc_ch, u16 value)
+{
+	ast_adc_write(ast_adc, 
+			(ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & ~AST_ADC_L_BOUND) |
+			value, 
+			AST_ADC_HYSTER0 + (adc_ch *4));
+
+}
+
+static u16
+ast_get_adc_hyster_upper(struct ast_adc_data *ast_adc, u8 adc_ch)
+{
+    u16 tmp=0;
+	tmp = ((ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & AST_ADC_H_BOUND) >> 16);
+
+//	printk("read val = %d \n",tmp);
+
+	return tmp;
+}
+
+static void
+ast_set_adc_hyster_upper(struct ast_adc_data *ast_adc, u8 adc_ch, u32 value)
+{
+	ast_adc_write(ast_adc, 
+			(ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & ~AST_ADC_H_BOUND) |
+			(value << 16), 
+			AST_ADC_HYSTER0 + (adc_ch *4));
+
+}
+
+static u8
+ast_get_adc_hyster_en(struct ast_adc_data *ast_adc, u8 adc_ch)
+{
+	//tacho source
+	if(ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & AST_ADC_HYSTER_EN)
+		return 1;
+	else
+		return 0;
+}
+
+static void
+ast_set_adc_hyster_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
+{
+	//tacho source 
+	if(enable == 1)
+		ast_adc_write(ast_adc,
+			ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) | AST_ADC_HYSTER_EN,
+			AST_ADC_HYSTER0 + (adc_ch *4));
+	else
+		ast_adc_write(ast_adc,
+			ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & ~AST_ADC_HYSTER_EN,
+			AST_ADC_HYSTER0 + (adc_ch *4));
+}
+
+static u16
+ast_get_adc_lower(struct ast_adc_data *ast_adc, u8 adc_ch)
+{
+    u16 tmp=0;
+	tmp = ast_adc_read(ast_adc, AST_ADC_BOUND0 + (adc_ch *4)) & AST_ADC_L_BOUND;
+
+//	printk("read val = %d \n",tmp);
+
+	return tmp;
+
+}
+
+static void
+ast_set_adc_lower(struct ast_adc_data *ast_adc, u8 adc_ch, u16 value)
+{
+	ast_adc_write(ast_adc, 
+			(ast_adc_read(ast_adc, AST_ADC_BOUND0 + (adc_ch *4)) & ~AST_ADC_L_BOUND) |
+			value, 
+			AST_ADC_BOUND0 + (adc_ch *4));
+
+}
+
+static u16
+ast_get_adc_upper(struct ast_adc_data *ast_adc, u8 adc_ch)
+{
+    u16 tmp=0;
+	tmp = ((ast_adc_read(ast_adc, AST_ADC_BOUND0 + (adc_ch *4)) & AST_ADC_H_BOUND) >> 16);
+
+	printk("read val = %d \n",tmp);
+
+	return tmp;
+
+
+}
+
+static void
+ast_set_adc_upper(struct ast_adc_data *ast_adc, u8 adc_ch, u32 value)
+{
+	ast_adc_write(ast_adc, 
+			(ast_adc_read(ast_adc, AST_ADC_BOUND0 + (adc_ch *4)) & ~AST_ADC_H_BOUND) |
+			(value << 16), 
+			AST_ADC_BOUND0 + (adc_ch *4));
+
+}
+
+
+static u8
+ast_get_adc_alarm(struct ast_adc_data *ast_adc, u8 adc_ch)
+{
+	//adc ch source 
+	if(ast_adc_read(ast_adc, AST_ADC_IER) & (0x1 << adc_ch))
+		return 1;
+	else
+		return 0;
+}
+
+static u16
+ast_get_adc_value(struct ast_adc_data *ast_adc, u8 adc_ch)
+{
+    int tmp;
+
+	switch(adc_ch) {
+		case 0:
+			tmp = ast_adc_read(ast_adc, AST_ADC_CH0_1) & AST_ADC_L_CH_MASK;
+			break;
+		case 1:
+			tmp = (ast_adc_read(ast_adc, AST_ADC_CH0_1) & AST_ADC_H_CH_MASK) >> 16;
+			break;	
+		case 2:
+			tmp = ast_adc_read(ast_adc, AST_ADC_CH2_3) & AST_ADC_L_CH_MASK;
+			break;
+		case 3:
+			tmp = (ast_adc_read(ast_adc, AST_ADC_CH2_3) & AST_ADC_H_CH_MASK) >> 16;
+			break;	
+		case 4:
+			tmp = ast_adc_read(ast_adc, AST_ADC_CH4_5) & AST_ADC_L_CH_MASK;
+			break;
+		case 5:
+			tmp = (ast_adc_read(ast_adc, AST_ADC_CH4_5) & AST_ADC_H_CH_MASK) >> 16;
+			break;	
+		case 6:
+			tmp = ast_adc_read(ast_adc, AST_ADC_CH6_7) & AST_ADC_L_CH_MASK;
+			break;
+		case 7:
+			tmp = (ast_adc_read(ast_adc, AST_ADC_CH6_7) & AST_ADC_H_CH_MASK) >> 16;
+			break;	
+		case 8:
+			tmp = ast_adc_read(ast_adc, AST_ADC_CH8_9) & AST_ADC_L_CH_MASK;
+			break;
+		case 9:
+			tmp = (ast_adc_read(ast_adc, AST_ADC_CH8_9) & AST_ADC_H_CH_MASK) >> 16;
+			break;	
+		case 10:
+			tmp = ast_adc_read(ast_adc, AST_ADC_CH10_11) & AST_ADC_L_CH_MASK;
+			break;
+		case 11:
+			tmp = (ast_adc_read(ast_adc, AST_ADC_CH10_11) & AST_ADC_H_CH_MASK) >> 16;
+			break;	
+		case 12:
+			tmp = ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_L_CH_MASK;
+			break;
+		case 13:
+			tmp = (ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_H_CH_MASK) >> 16;
+			break;	
+		case 14:
+			tmp = ast_adc_read(ast_adc, AST_ADC_CH14_15) & AST_ADC_L_CH_MASK;
+			break;
+		case 15:
+			tmp = (ast_adc_read(ast_adc, AST_ADC_CH14_15) & AST_ADC_H_CH_MASK) >> 16;
+			break;	
+
+	}
+
+	tmp += ast_adc->compen_value;
+
+//	printk("voltage = %d \n",tmp);
+	
+	return tmp;
+
+}
+
+static u8 
+ast_get_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch)
+{
+    u8 tmp=0;
+
+	if(ast_adc_read(ast_adc, AST_ADC_CTRL) & (0x1 << (16+adc_ch)))
+		tmp = 1;
+	else
+		tmp = 0;
+
+	return tmp;
+
+}
+
+static void 
+ast_set_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
+{
+	if(enable)
+		ast_adc_write(ast_adc, ast_adc_read(ast_adc, AST_ADC_CTRL) | (0x1 << (16+adc_ch)), AST_ADC_CTRL);
+	else
+		ast_adc_write(ast_adc, ast_adc_read(ast_adc, AST_ADC_CTRL) & ~(0x1 << (16+adc_ch)), AST_ADC_CTRL);
+}
+
+
+/* attr ADC sysfs 0~max adc channel 
+*	 0 - show/store channel enable
+*	 1 - show value 
+*	 2 - show alarm   get statuse
+*	 3 - show/store upper
+*	 4 - show/store lower 
+*	 5 - show/store hystersis enable  
+*	 6 - show/store hystersis upper  
+*	 7 - show/store hystersis low  
+*/
+
+static ssize_t 
+ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+{
+	struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+	u16 tmp;
+	u32 voltage,tmp1, tmp2,tmp3;
+
+	//sensor_attr->index : pwm_ch#
+	//sensor_attr->nr : attr#
+	switch(sensor_attr->nr) 
+	{
+		case 0: //channel enable, disable
+			return sprintf(sysfsbuf, "%d : %s\n", ast_get_adc_en(ast_adc,sensor_attr->index),ast_get_adc_en(ast_adc,sensor_attr->index) ? "Enable":"Disable");
+			break;
+		case 1: //value
+			tmp = ast_get_adc_value(ast_adc, sensor_attr->index);
+			//Voltage Sense Method
+			tmp1 = (adc_vcc_ref[REST_DESIGN].r1 + adc_vcc_ref[REST_DESIGN].r2) * tmp * 25 * 10;
+			tmp2 = adc_vcc_ref[REST_DESIGN].r2 * 1023 ;
+		
+			tmp3 = (adc_vcc_ref[REST_DESIGN].r1 * adc_vcc_ref[REST_DESIGN].v2) / adc_vcc_ref[REST_DESIGN].r2;
+		//	printk("tmp3 = %d \n",tmp3);
+			voltage = (tmp1/tmp2) - tmp3;
+			
+			return sprintf(sysfsbuf, "%d.%d (V)\n",voltage/100, voltage%100);
+			break;
+		case 2: //alarm
+			return sprintf(sysfsbuf, "%d \n", ast_get_adc_alarm(ast_adc,sensor_attr->index));
+			break;			
+		case 3: //upper
+			return sprintf(sysfsbuf, "%d \n", ast_get_adc_upper(ast_adc,sensor_attr->index));
+			break;			
+		case 4: //lower
+			return sprintf(sysfsbuf, "%d \n", ast_get_adc_lower(ast_adc,sensor_attr->index));
+			break;			
+		case 5: //hystersis enable 
+			return sprintf(sysfsbuf, "%d : %s\n", ast_get_adc_hyster_en(ast_adc,sensor_attr->index),ast_get_adc_hyster_en(ast_adc,sensor_attr->index) ? "Enable":"Disable");
+			break;			
+		case 6: //hystersis upper
+			return sprintf(sysfsbuf, "%d \n", ast_get_adc_hyster_upper(ast_adc,sensor_attr->index));
+			break;			
+		case 7: //hystersis lower
+			return sprintf(sysfsbuf, "%d \n", ast_get_adc_hyster_lower(ast_adc,sensor_attr->index));
+			break;			
+
+		default:
+			return -EINVAL;
+			break;
+	}
+}
+
+static ssize_t 
+ast_store_adc(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
+{
+	u32 input_val;
+	struct sensor_device_attribute_2 *sensor_attr =
+						to_sensor_dev_attr_2(attr);
+
+	input_val = simple_strtoul(sysfsbuf, NULL, 10);
+
+	//sensor_attr->index : pwm_ch#
+	//sensor_attr->nr : attr#
+	switch(sensor_attr->nr) 
+	{
+		case 0: //enable, disable
+			ast_set_adc_en(ast_adc, sensor_attr->index, input_val);
+			break;
+		case 1: //value
+			
+			break;
+		case 2: //alarm
+			break;			
+		case 3:
+			ast_set_adc_upper(ast_adc, sensor_attr->index, input_val);
+			break;
+		case 4:
+			ast_set_adc_lower(ast_adc, sensor_attr->index, input_val);
+			break;
+		case 5: //hystersis
+			ast_set_adc_hyster_en(ast_adc, sensor_attr->index, input_val);
+			break;			
+		case 6:
+			ast_set_adc_hyster_upper(ast_adc, sensor_attr->index, input_val);
+			break;
+		case 7:
+			ast_set_adc_hyster_lower(ast_adc, sensor_attr->index, input_val);
+			break;
+			
+		default:
+			return -EINVAL;
+			break;
+	}
+
+	return count;
+}
+
+/* attr ADC sysfs 0~max adc channel 
+*	 0 - show/store channel enable
+*	 1 - show value 
+*	 2 - show alarm   get statuse
+*	 3 - show/store upper
+*	 4 - show/store lower 
+*	 5 - show/store hystersis enable  
+*	 6 - show/store hystersis upper  
+*	 7 - show/store hystersis low  
+*/
+
+#define sysfs_adc_ch(index) \
+static SENSOR_DEVICE_ATTR_2(adc##index##_en, S_IRUGO | S_IWUSR, \
+	ast_show_adc, ast_store_adc, 0, index); \
+\
+static SENSOR_DEVICE_ATTR_2(adc##index##_value, S_IRUGO | S_IWUSR, \
+	ast_show_adc, NULL, 1, index); \
+\
+static SENSOR_DEVICE_ATTR_2(adc##index##_alarm, S_IRUGO | S_IWUSR, \
+	ast_show_adc, NULL, 2, index); \
+\
+static SENSOR_DEVICE_ATTR_2(adc##index##_upper, S_IRUGO | S_IWUSR, \
+	ast_show_adc, ast_store_adc, 3, index); \
+\
+static SENSOR_DEVICE_ATTR_2(adc##index##_lower, S_IRUGO | S_IWUSR, \
+	ast_show_adc, ast_store_adc, 4, index); \
+\
+static SENSOR_DEVICE_ATTR_2(adc##index##_hyster_en, S_IRUGO | S_IWUSR, \
+	ast_show_adc, ast_store_adc, 5, index); \
+\
+static SENSOR_DEVICE_ATTR_2(adc##index##_hyster_upper, S_IRUGO | S_IWUSR, \
+	ast_show_adc, ast_store_adc, 6, index); \
+\
+static SENSOR_DEVICE_ATTR_2(adc##index##_hyster_lower, S_IRUGO | S_IWUSR, \
+	ast_show_adc, ast_store_adc, 7, index); \
+\
+static struct attribute *adc##index##_attributes[] = { \
+	&sensor_dev_attr_adc##index##_en.dev_attr.attr, \
+	&sensor_dev_attr_adc##index##_value.dev_attr.attr, \
+	&sensor_dev_attr_adc##index##_alarm.dev_attr.attr, \
+	&sensor_dev_attr_adc##index##_upper.dev_attr.attr, \
+	&sensor_dev_attr_adc##index##_lower.dev_attr.attr, \
+	&sensor_dev_attr_adc##index##_hyster_en.dev_attr.attr, \
+	&sensor_dev_attr_adc##index##_hyster_upper.dev_attr.attr, \
+	&sensor_dev_attr_adc##index##_hyster_lower.dev_attr.attr, \
+	NULL \
+};
+
+/*
+ * Create the needed functions for each pwm using the macro defined above
+ * (4 pwms are supported)
+ */
+sysfs_adc_ch(0);
+sysfs_adc_ch(1);
+sysfs_adc_ch(2);
+sysfs_adc_ch(3);
+sysfs_adc_ch(4);
+sysfs_adc_ch(5);
+sysfs_adc_ch(6);
+sysfs_adc_ch(7);
+sysfs_adc_ch(8);
+sysfs_adc_ch(9);
+sysfs_adc_ch(10);
+sysfs_adc_ch(11);
+#if defined(CONFIG_ARCH_AST2400) || defined(CONFIG_ARCH_AST2500)
+sysfs_adc_ch(12);
+sysfs_adc_ch(13);
+sysfs_adc_ch(14);
+sysfs_adc_ch(15);
+#endif
+
+static const struct attribute_group adc_attribute_groups[] = {
+	{ .attrs = adc0_attributes },
+	{ .attrs = adc1_attributes },
+	{ .attrs = adc2_attributes },
+	{ .attrs = adc3_attributes },
+	{ .attrs = adc4_attributes },
+	{ .attrs = adc5_attributes },
+	{ .attrs = adc6_attributes },
+	{ .attrs = adc7_attributes },
+	{ .attrs = adc8_attributes },
+	{ .attrs = adc9_attributes },
+	{ .attrs = adc10_attributes },	
+	{ .attrs = adc11_attributes },
+#if defined(CONFIG_ARCH_AST2400) || defined(CONFIG_ARCH_AST2500)
+	{ .attrs = adc12_attributes },
+	{ .attrs = adc13_attributes },
+	{ .attrs = adc14_attributes },
+	{ .attrs = adc15_attributes },
+#endif	
+};
+
+
+static int 
+ast_adc_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	int err;
+	int ret=0;
+	int i;
+
+	dev_dbg(&pdev->dev, "ast_adc_probe \n");
+
+	ast_adc = kzalloc(sizeof(struct ast_adc_data), GFP_KERNEL);
+	if (!ast_adc) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (NULL == res) {
+		dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
+		ret = -ENOENT;
+		goto out_mem;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res), res->name)) {
+		dev_err(&pdev->dev, "cannot reserved region\n");
+		ret = -ENXIO;
+		goto out_mem;
+	}
+
+	ast_adc->reg_base = ioremap(res->start, resource_size(res));
+	if (!ast_adc->reg_base) {
+		ret = -EIO;
+		goto out_region;
+	}
+
+	ast_adc->irq = platform_get_irq(pdev, 0);
+	if (ast_adc->irq < 0) {
+		dev_err(&pdev->dev, "no irq specified\n");
+		ret = -ENOENT;
+		goto out_region;
+	}
+
+	/* Register sysfs hooks */
+	ast_adc->hwmon_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(ast_adc->hwmon_dev)) {
+		ret = PTR_ERR(ast_adc->hwmon_dev);
+		goto out_region;
+	}
+
+	for(i=0; i<MAX_CH_NO; i++) {
+		err = sysfs_create_group(&pdev->dev.kobj, &adc_attribute_groups[i]);
+		if (err)
+			goto out_region;
+	}
+
+	ast_adc_ctrl_init();
+	
+	printk(KERN_INFO "ast_adc: driver successfully loaded.\n");
+
+	return 0;
+
+
+//out_irq:
+//	free_irq(ast_adc->irq, NULL);
+out_region:
+	release_mem_region(res->start, res->end - res->start + 1);
+out_mem:
+	kfree(ast_adc);
+out:
+	printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
+	return ret;
+}
+
+static int 
+ast_adc_remove(struct platform_device *pdev)
+{
+	int i=0;
+	struct ast_adc_data *ast_adc = platform_get_drvdata(pdev);
+	struct resource *res;
+	printk(KERN_INFO "ast_adc: driver unloaded.\n");
+
+    hwmon_device_unregister(ast_adc->hwmon_dev);
+
+	for(i=0; i<5; i++)
+		sysfs_remove_group(&pdev->dev.kobj, &adc_attribute_groups[i]);
+
+	platform_set_drvdata(pdev, NULL);
+//	free_irq(ast_adc->irq, ast_adc);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	iounmap(ast_adc->reg_base);
+	release_mem_region(res->start, res->end - res->start + 1);
+	kfree(ast_adc);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int 
+ast_adc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	printk("ast_adc_suspend : TODO \n");
+	return 0;
+}
+
+static int 
+ast_adc_resume(struct platform_device *pdev)
+{
+	ast_adc_ctrl_init();
+	return 0;
+}
+
+#else
+#define ast_adc_suspend        NULL
+#define ast_adc_resume         NULL
+#endif
+
+static struct platform_driver ast_adc_driver = {
+	.probe			= ast_adc_probe,
+	.remove 		= __devexit_p(ast_adc_remove),
+    .suspend        = ast_adc_suspend,
+    .resume         = ast_adc_resume,
+    .driver         = {
+            .name   = "ast_adc",
+            .owner  = THIS_MODULE,
+    },
+};
+
+static int __init 
+ast_adc_init(void)
+{
+	return platform_driver_register(&ast_adc_driver);
+}
+
+static void __exit 
+ast_adc_exit(void)
+{
+	platform_driver_unregister(&ast_adc_driver);
+}
+
+module_init(ast_adc_init);
+module_exit(ast_adc_exit);
+
+MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
+MODULE_DESCRIPTION("ADC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/ast_lcp_80h.c b/drivers/hwmon/ast_lcp_80h.c
new file mode 100755
index 0000000..681d2d6
--- /dev/null
+++ b/drivers/hwmon/ast_lcp_80h.c
@@ -0,0 +1,312 @@
+/*
+ *  ast_lpc_snoop.c
+ *
+ *  ASPEED LPC Snoop controller driver
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *  History:
+ *    2012.11.26: Initial version [Ryan Chen]
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/mutex.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon.h>
+#include <linux/workqueue.h>
+#include <linux/sysfs.h>
+#include <linux/err.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <plat/regs-1070_lpc.h>
+
+struct ast_clpc_data {
+	struct device			*hwmon_dev;
+	void __iomem			*reg_base;			/* virtual */
+	int 					irq;				//ADC IRQ number 
+	u8 						80h_data;			//80h_data
+};
+
+static inline void
+ast_clpc_write(struct ast_clpc_data *ast_clpc, u32 val, u32 reg)
+{
+//	printk("write offset: %x, val: %x \n",reg,val);
+	writel(val, ast_clpc->reg_base+ reg);
+}
+
+static inline u32
+ast_clpc_read(struct ast_adc_data *ast_clpc, u32 reg)
+{
+	u32 val = readl(ast_clpc->reg_base + reg);
+//	printk("read offset: %x, val: %x \n",reg,val);
+	return val;
+}
+
+static irqreturn_t ast_lpc_80h_handler(int irq, void *dev_id)
+{
+	struct ast_clpc_data *ast_clpc = dev_id;
+	u32 sts = ast_clpc_read(ast_clpc, AST1070_LPC_80H_CTRL);
+
+	if(isr_sts & AST1070_LPC_80H_CLR) {
+		ast_clpc->80h_data = ast_clpc_read(ast_clpc, AST1070_LPC_80H_DATA);	
+		ast_clpc_write(ast_clpc, AST1070_LPC_80H_CLR, AST1070_LPC_80H_DATA);	
+	} else
+		printk("IRQ ISSUE bug \n");
+
+	return IRQ_HANDLED;
+
+}
+
+static void ast_clpc_80h_init(struct ast_clpc_data *ast_clpc, u16 addr)
+{
+	ast_clpc_write(ast_clpc, AST1070_LPC_80H_CLR, AST1070_LPC_80H_CTRL);
+	
+	//Snoop Port
+	ast_clpc_write(ast_clpc, addr & 0xff, AST1070_LPC_L_80H_ADDR);
+	ast_clpc_write(ast_clpc, (addr & 0xff) >> 8 , AST1070_LPC_H_80H_ADDR);
+	//Clear Interrupt and Enable
+	//AST1070 BUG :===: D[4] W1C	
+	ast_clpc_write(ast_clpc, AST1070_LPC_80H_CLR, AST1070_LPC_80H_DATA);		
+	ast_clpc_write(ast_clpc, AST1070_LPC_80H_CLR | AST1070_LPC_80H_EN, AST1070_LPC_80H_CTRL);
+}
+
+/* attr 80H sysfs 0~max adc channel 
+*	 0 - show/store 80h addr
+*	 1 - show 80h data
+*/
+
+static ssize_t 
+ast_show_clpc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+{
+	struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+	u16 tmp;
+	u32 voltage,tmp1, tmp2,tmp3;
+
+	//sensor_attr->index : pwm_ch#
+	//sensor_attr->nr : attr#
+	switch(sensor_attr->nr) 
+	{
+		case 0: //channel enable, disable
+			return sprintf(sysfsbuf, "%d \n", ast_clpc->80h_data);
+			break;
+
+		default:
+			return -EINVAL;
+			break;
+	}
+}
+
+static ssize_t 
+ast_store_clpc(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
+{
+	u32 input_val;
+	struct sensor_device_attribute_2 *sensor_attr =
+						to_sensor_dev_attr_2(attr);
+
+	input_val = simple_strtoul(sysfsbuf, NULL, 10);
+
+	//sensor_attr->index : pwm_ch#
+	//sensor_attr->nr : attr#
+	switch(sensor_attr->nr) 
+	{
+		case 0: //enable, disable
+
+			break;
+		default:
+			return -EINVAL;
+			break;
+	}
+
+	return count;
+}
+
+/* attr ADC sysfs 0~max adc channel 
+*	 0 - show 80h data
+*/
+
+#define sysfs_clpc(index) \
+static SENSOR_DEVICE_ATTR_2(clpc##index##_en, S_IRUGO | S_IWUSR, \
+	ast_show_clpc, NULL, 0, index); \
+\
+static struct attribute *clpc##index##_attributes[] = { \
+	&sensor_dev_attr_clpc##index##_80h.dev_attr.attr, \
+	NULL \
+};
+
+/*
+ * Create the needed functions for each pwm using the macro defined above
+ * (4 pwms are supported)
+ */
+sysfs_clpc(0);
+
+static const struct attribute_group clpc_attribute_groups[] = {
+	{ .attrs = clpc0_attributes },
+};
+
+
+static int 
+ast_clpc_probe(struct platform_device *pdev)
+{
+	struct ast_clpc_data *ast_clpc;
+	struct resource *res;
+	int err;
+	int ret=0;
+	int i;
+
+	dev_dbg(&pdev->dev, "ast_clpc_probe \n");
+
+	ast_clpc = kzalloc(sizeof(struct ast_clpc_data), GFP_KERNEL);
+	if (!ast_adc) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (NULL == res) {
+		dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
+		ret = -ENOENT;
+		goto out_mem;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res), res->name)) {
+		dev_err(&pdev->dev, "cannot reserved region\n");
+		ret = -ENXIO;
+		goto out_mem;
+	}
+
+	ast_clpc->reg_base = ioremap(res->start, resource_size(res));
+	if (!ast_clpc->reg_base) {
+		ret = -EIO;
+		goto out_region;
+	}
+
+	ast_clpc->irq = platform_get_irq(pdev, 3);
+	if (ast_clpc->irq < 0) {
+		dev_err(&pdev->dev, "no irq specified\n");
+		ret = -ENOENT;
+		goto out_region;
+	}
+
+
+	/* Register sysfs hooks */
+	ast_clpc->hwmon_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(ast_clpc->hwmon_dev)) {
+		ret = PTR_ERR(ast_clpc->hwmon_dev);
+		goto out_region;
+	}
+
+	for(i=0; i< MAX_CH_NO; i++) {
+		err = sysfs_create_group(&pdev->dev.kobj, &clpc_attribute_groups[i]);
+		if (err)
+			goto out_region;
+	}
+
+	ast_clpc_80h_init();
+
+	ret = request_irq(ast_clpc->irq, ast_lpc_handler, IRQF_SHARED,
+			  i2c_dev->adap.name, i2c_dev);
+	if (ret) {
+		printk(KERN_INFO "I2C: Failed request irq %d\n", i2c_dev->irq);
+		goto out_region;
+	}
+
+	platform_set_drvdata(pdev, ast_clpc);
+	
+	printk(KERN_INFO "ast_adc: driver successfully loaded.\n");
+
+	return 0;
+
+
+//out_irq:
+//	free_irq(ast_clpc->irq, NULL);
+out_region:
+	release_mem_region(res->start, res->end - res->start + 1);
+out_mem:
+	kfree(ast_clpc);
+out:
+	printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
+	return ret;
+}
+
+static int 
+ast_adc_remove(struct platform_device *pdev)
+{
+	int i=0;
+	struct ast_adc_data *ast_clpc = platform_get_drvdata(pdev);
+	struct resource *res;
+	printk(KERN_INFO "ast_adc: driver unloaded.\n");
+
+    hwmon_device_unregister(ast_clpc->hwmon_dev);
+
+	for(i=0; i<5; i++)
+		sysfs_remove_group(&pdev->dev.kobj, &clpc_attribute_groups[i]);
+
+	platform_set_drvdata(pdev, NULL);
+//	free_irq(ast_adc->irq, ast_adc);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	iounmap(ast_clpc->reg_base);
+	release_mem_region(res->start, res->end - res->start + 1);
+	kfree(ast_clpc);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int 
+ast_adc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	printk("ast_adc_suspend : TODO \n");
+	return 0;
+}
+
+static int 
+ast_adc_resume(struct platform_device *pdev)
+{
+	ast_adc_ctrl_init();
+	return 0;
+}
+
+#else
+#define ast_adc_suspend        NULL
+#define ast_adc_resume         NULL
+#endif
+
+static struct platform_driver ast_adc_driver = {
+	.probe			= ast_adc_probe,
+	.remove 		= __devexit_p(ast_adc_remove),
+    .suspend        = ast_adc_suspend,
+    .resume         = ast_adc_resume,
+    .driver         = {
+            .name   = "ast_adc",
+            .owner  = THIS_MODULE,
+    },
+};
+
+static int __init 
+ast_adc_init(void)
+{
+	return platform_driver_register(&ast_adc_driver);
+}
+
+static void __exit 
+ast_adc_exit(void)
+{
+	platform_driver_unregister(&ast_adc_driver);
+}
+
+module_init(ast_adc_init);
+module_exit(ast_adc_exit);
+
+MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
+MODULE_DESCRIPTION("ADC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/ast_pwm_fan.c b/drivers/hwmon/ast_pwm_fan.c
new file mode 100644
index 0000000..02784c5
--- /dev/null
+++ b/drivers/hwmon/ast_pwm_fan.c
@@ -0,0 +1,2129 @@
+/*
+ *  ast_pwm_fan.c
+ *
+ *  ASPEED PWM & Fan Tacho controller driver
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *  History:
+ *    2012.08.06: Initial version [Ryan Chen]
+ */
+/* CLK sysfs
+* 0 : enable
+* 1 : clk_source */
+
+/* PWM sysfs A~H (0~7)
+*  0 - show/store enable
+*  1 - show/store type
+*  2 - show/store falling
+*  3 - show/store rising */
+
+/*PWM M/N/O Type sysfs
+*  0 - show/store unit
+*  1 - show/store division_l
+*  2 - show/store division_h */
+
+/* FAN sysfs (0~15)
+*  - show/store enable
+*  - show/store source
+*  - show/store rpm
+*  - show/store alarm
+*  - show/store alarm_en */
+
+/* Fan M/N/O Type sysfs 
+*  0 - show/store enable
+*  1 - show/store mode
+*  2 - show/store unit
+*  3 - show/store division
+*  4 - show/store limit */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/mutex.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon.h>
+#include <linux/workqueue.h>
+#include <linux/sysfs.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_COLDFIRE
+#include <asm/arch/regs-pwm_fan.h>
+#include <asm/arch/ast_pwm_techo.h>
+#else
+#include <plat/regs-pwm_fan.h>
+#include <mach/ast_pwm_techo.h>
+#endif
+
+//#define MCLK	1
+
+struct ast_pwm_tacho_data {
+	struct device			*hwmon_dev;
+	void __iomem			*reg_base;			/* virtual */
+	int 					irq;				
+	struct ast_pwm_driver_data *ast_pwm_data;	
+};
+
+struct ast_pwm_tacho_data *ast_pwm_tacho;
+
+static u8 ast_get_pwm_type(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch);
+static u8 ast_get_pwm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch);
+static u8 ast_get_tacho_type_division(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type);
+static u16 ast_get_tacho_type_unit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type);
+static u8 ast_get_pwm_clock_division_h(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type);
+static u8 ast_get_pwm_clock_division_l(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type);
+static u8 ast_get_pwm_clock_unit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type);
+
+static inline void
+ast_pwm_tacho_write(struct ast_pwm_tacho_data *ast_pwm_tacho, u32 val, u32 reg)
+{
+//	printk("write offset: %x, val: %x \n",reg,val);
+	writel(val, ast_pwm_tacho->reg_base+ reg);
+}
+
+static inline u32
+ast_pwm_tacho_read(struct ast_pwm_tacho_data *ast_pwm_tacho, u32 reg)
+{
+	u32 val = readl(ast_pwm_tacho->reg_base + reg);
+//	printk("read offset: %x, val: %x \n",reg,val);
+	return val;
+}
+
+/////////////////////////////////////////
+/*
+//1. The PWM base clock = 24Mhz / (Clock_Division_H D[7:4] in PTCR04 * Clock_Division_L D[3:0] in PTCR04)
+//2. The frequency of PWM = The PWM base clock / (PWM period D[15:8] in PTCR04 + 1)
+//3. If you plan to output 25Khz PWM frequency and 10% step of duty cycle, we suggest to set 0x943 in PTCR04 register.
+//   The PWM frequency = 24Mhz / (16 * 6 * (9 + 1)) = 25Khz
+//   duty cycle settings in the PTCR08 register:
+//   0x1e786008 D[15:0] = 0x0900, duty = 90%
+//   0x1e786008 D[15:0] = 0x0902, duty = 70%
+//   .
+//   .
+//   .
+//   0x1e786008 D[15:0] = 0x0908, duty = 10%
+//   0x1e786008 D[15:0] = 0x0909, duty = 100%
+//   0x1e786008 D[15:0] = 0x0000, duty = 100%
+	(falling) - (rising+1) /unit
+*/
+
+static void ast_pwm_taco_init(void)
+{
+	//Enable PWM TACH CLK **************************************************
+	// Set M/N/O out is 25Khz
+	//The PWM frequency = 24Mhz / (16 * 6 * (9 + 1)) = 25Khz
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x09430943, AST_PTCR_CLK_CTRL);
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x0943, AST_PTCR_CLK_EXT_CTRL);
+
+	//FULL SPEED at initialize 100% pwm A~H
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_DUTY0_CTRL);
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_DUTY1_CTRL);
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_DUTY2_CTRL);
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_DUTY3_CTRL);
+
+	//Set TACO M/N/O initial unit 0x1000, falling , divide 4 , Enable
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x10000001, AST_PTCR_TYPEM_CTRL0);
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x10000001, AST_PTCR_TYPEN_CTRL0);
+#ifdef PWM_TYPE_O	
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x10000001, AST_PTCR_TYPEO_CTRL0);
+#endif
+
+	// TACO measure period = 24000000 / 2 / 2 / 256 / 4096 / 1 (only enable 1 TACHO) = 5.72Hz, it means that software needs to
+	//	 wait at least 0.2 sec to get refreshed TACO value. If you will enable more TACO or require faster response, you have to
+	//	 control the clock divisor and the period to be smaller
+
+	//Full Range to do measure unit 0x1000
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x10000000, AST_PTCR_TYPEM_CTRL1);
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x10000000, AST_PTCR_TYPEN_CTRL1);
+#ifdef PWM_TYPE_O	
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x10000000, AST_PTCR_TYPEO_CTRL1);
+#endif
+
+	//TACO Source Selection, PWMA for fan0~15 
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_TACH_SOURCE);
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_TACH_SOURCE_EXT);
+
+	//PWM A~D -> Disable , type M, 
+	//Tacho 0~15 Disable
+	//CLK source 24Mhz
+#ifdef MCLK
+	ast_pwm_tacho_write(ast_pwm_tacho, AST_PTCR_CTRL_CLK_MCLK | AST_PTCR_CTRL_CLK_EN, AST_PTCR_CTRL);
+#else
+	ast_pwm_tacho_write(ast_pwm_tacho, AST_PTCR_CTRL_CLK_EN, AST_PTCR_CTRL);
+#endif
+	
+}
+
+/*index 0 : clk_en , 1: clk_source*/
+static ssize_t 
+ast_store_clk(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
+{
+	u32 input_val;
+	struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+
+	input_val = simple_strtoul(sysfsbuf, NULL, 10);
+
+	if ((input_val > 1) || (input_val < 0)) 
+		return -EINVAL;
+
+	//sensor_attr->index : tacho#
+	//sensor_attr->nr : attr#
+	switch(sensor_attr->nr)	
+	{
+		case 0:	//clk_en
+			if(input_val)
+				ast_pwm_tacho_write(ast_pwm_tacho,
+						ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_CLK_EN,
+						AST_PTCR_CTRL);
+			else
+				ast_pwm_tacho_write(ast_pwm_tacho,
+						ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_CLK_EN,
+						AST_PTCR_CTRL);
+			break;
+		case 1: //clk_source
+			if(input_val) {
+				ast_pwm_tacho_write(ast_pwm_tacho,
+						ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_CLK_MCLK,
+						AST_PTCR_CTRL);
+			} else {
+				ast_pwm_tacho_write(ast_pwm_tacho,
+						ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_CLK_MCLK,
+						AST_PTCR_CTRL);
+			}
+			break;
+		default:
+			return -EINVAL;
+			break;
+	}
+
+	return count;
+
+}
+
+
+static ssize_t 
+ast_show_clk(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+{
+	struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+
+	//sensor_attr->index : fan#
+	//sensor_attr->nr : attr#
+	switch(sensor_attr->nr)	
+	{
+		case 0:	//clk_en
+			if(AST_PTCR_CTRL_CLK_EN & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL))
+				return sprintf(sysfsbuf, "1: Enable\n");
+			else
+				return sprintf(sysfsbuf, "0: Disable\n");
+			break;
+		case 1: //clk_source
+			if(AST_PTCR_CTRL_CLK_MCLK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL))
+					return sprintf(sysfsbuf, "1: MCLK \n");
+				else
+					return sprintf(sysfsbuf, "0: 24Mhz\n");
+
+			break;
+		default:
+			return sprintf(sysfsbuf, "ERROR CLK Index\n");
+			break;
+	}
+}
+
+static u32
+ast_get_tacho_measure_period(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
+{
+	u32 clk,clk_unit,div_h,div_l,tacho_unit,tacho_div;
+	//TODO ... 266
+	if(AST_PTCR_CTRL_CLK_MCLK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL)) {
+		//TODO .....
+		clk = ast_pwm_tacho->ast_pwm_data->get_pwm_clock();
+	} else
+		clk = 24*1000*1000;
+	
+	clk_unit = ast_get_pwm_clock_unit(ast_pwm_tacho,pwm_type);
+	div_h = ast_get_pwm_clock_division_h(ast_pwm_tacho,pwm_type);
+	div_h = 0x1 << div_h;
+	div_l = ast_get_pwm_clock_division_l(ast_pwm_tacho,pwm_type);
+//	div_l = (div_l) << 1;
+	if(div_l == 0)
+		div_l = 1;
+	else
+		div_l = div_l * 2; 
+	
+	tacho_unit = ast_get_tacho_type_unit(ast_pwm_tacho,pwm_type);
+	tacho_div = ast_get_tacho_type_division(ast_pwm_tacho,pwm_type);
+
+	tacho_div = 0x4 << (tacho_div*2);
+//	printk("clk %d,clk_unit %d, div_h %d, div_l %d, tacho_unit %d, tacho_div %d\n",clk,clk_unit, div_h, div_l, tacho_unit, tacho_div);
+	return clk/(clk_unit*div_h*div_l*tacho_div*tacho_unit);
+}
+
+static u8
+ast_get_tacho_type_division(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
+{
+	u32 tmp = 0;
+	switch(pwm_type) {
+		case PWM_TYPE_M:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0);
+			break;
+		case PWM_TYPE_N:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0);
+			break;
+#ifdef PWM_TYPE_O			
+		case PWM_TYPE_O:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0);
+			break;
+#endif			
+		default:
+			printk("error type !! \n");
+			break;
+			
+	}
+
+	return ((tmp & TYPE_CTRL0_CLK_DIVISION_MASK) >> TYPE_CTRL0_CLK_DIVISION);
+}
+
+static void
+ast_set_tacho_type_division(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type, u32 division)
+{
+	u32 tmp = 0;
+	if(division > 0x7)
+		return;
+
+	switch(pwm_type) {
+		case PWM_TYPE_M:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0);
+			break;
+		case PWM_TYPE_N:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0);
+			break;
+#ifdef PWM_TYPE_O			
+		case PWM_TYPE_O:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0);
+			break;
+#endif			
+		default:
+			printk("ERROR type !! \n");
+			break;
+	}
+
+	tmp &= ~TYPE_CTRL0_CLK_DIVISION_MASK;
+	tmp |= (division << TYPE_CTRL0_CLK_DIVISION);
+
+	switch(pwm_type) {
+		case PWM_TYPE_M:
+			ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEM_CTRL0);
+			break;
+		case PWM_TYPE_N:
+			ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEN_CTRL0);
+			break;
+#ifdef PWM_TYPE_O			
+		case PWM_TYPE_O:
+			ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEO_CTRL0);
+			break;
+#endif			
+		default:
+			printk("ERROR type !! \n");
+			break;
+	}
+	
+}
+
+static u16
+ast_get_tacho_type_unit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
+{
+	u32 tmp = 0;
+
+	switch(pwm_type) {
+		case PWM_TYPE_M:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0);
+			break;
+		case PWM_TYPE_N:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0);
+			break;
+#ifdef PWM_TYPE_O			
+		case PWM_TYPE_O:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0);
+			break;
+#endif			
+		default:
+			printk("ERROR type !! \n");
+			break;
+	}
+	
+	return ((tmp & TYPE_CTRL0_FAN_PERIOD_MASK) >> TYPE_CTRL0_FAN_PERIOD);
+}
+
+static void
+ast_set_tacho_type_unit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type,u32 unit)
+{
+	u32 tmp = 0;
+
+	if(unit > 0xffff)
+		return;
+
+	switch(pwm_type) {
+		case PWM_TYPE_M:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0);
+			break;
+		case PWM_TYPE_N:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0);
+			break;
+#ifdef PWM_TYPE_O			
+		case PWM_TYPE_O:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0);
+			break;
+#endif			
+		default:
+			printk("ERROR type !! \n");
+			break;
+	}	
+
+	tmp &= ~TYPE_CTRL0_FAN_PERIOD_MASK;
+	tmp |= (unit << TYPE_CTRL0_FAN_PERIOD);
+
+	switch(pwm_type) {
+		case PWM_TYPE_M:
+			ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEM_CTRL0);
+			break;
+		case PWM_TYPE_N:
+			ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEN_CTRL0);
+			break;
+#ifdef PWM_TYPE_O			
+		case PWM_TYPE_O:
+			ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEO_CTRL0);
+			break;
+#endif			
+		default:
+			printk("ERROR type !! \n");
+			break;
+	}	
+	
+}
+
+static u32
+ast_get_tacho_type_mode(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
+{
+	u32 tmp = 0;
+
+	switch(pwm_type) {
+		case PWM_TYPE_M:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0);
+			break;
+		case PWM_TYPE_N:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0);
+			break;
+#ifdef PWM_TYPE_O			
+		case PWM_TYPE_O:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0);
+			break;
+#endif			
+		default:
+			printk("ERROR type !! \n");
+			break;
+	}	
+
+	return ((tmp & TYPE_CTRL0_FAN_MODE_MASK) >> TYPE_CTRL0_FAN_MODE);
+}
+
+static void
+ast_set_tacho_type_mode(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type,u32 mode)
+{
+	u32 tmp = 0;
+	if(mode > 0x2)
+		return;
+
+	switch(pwm_type) {
+		case PWM_TYPE_M:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0);
+			break;
+		case PWM_TYPE_N:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0);
+			break;
+#ifdef PWM_TYPE_O			
+		case PWM_TYPE_O:
+			tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0);
+			break;
+#endif			
+		default:
+			printk("ERROR type !! \n");
+			break;
+	}	
+
+	tmp &= ~TYPE_CTRL0_FAN_MODE_MASK;
+	tmp |= (mode << TYPE_CTRL0_FAN_MODE);
+
+	switch(pwm_type) {
+		case PWM_TYPE_M:
+			ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEM_CTRL0);
+			break;
+		case PWM_TYPE_N:
+			ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEN_CTRL0);
+			break;
+#ifdef PWM_TYPE_O			
+		case PWM_TYPE_O:
+			ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEO_CTRL0);
+			break;
+#endif			
+		default:
+			printk("ERROR type !! \n");
+			break;
+	}	
+
+}
+
+static u8
+ast_get_tacho_type_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
+{
+	u8 tmp;
+	switch(pwm_type) {
+		case PWM_TYPE_M:
+			tmp = (TYPE_CTRL0_FAN_TYPE_EN & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0));
+			break;
+		case PWM_TYPE_N:
+			tmp = (TYPE_CTRL0_FAN_TYPE_EN & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0));
+			break;
+#ifdef PWM_TYPE_O			
+		case PWM_TYPE_O:
+			tmp = (TYPE_CTRL0_FAN_TYPE_EN & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0));
+			break;
+#endif			
+		default:
+			printk("ERROR type !! \n");
+			break;
+	}	
+
+	return tmp;
+}
+
+static void
+ast_set_tacho_type_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type,u32 enable)
+{
+	switch(pwm_type) {
+		case PWM_TYPE_M:
+			ast_pwm_tacho_write(ast_pwm_tacho, 
+				ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0) | enable, 
+				AST_PTCR_TYPEM_CTRL0);
+
+			break;
+		case PWM_TYPE_N:
+			ast_pwm_tacho_write(ast_pwm_tacho, 
+			ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0) | enable, 
+			AST_PTCR_TYPEN_CTRL0);
+
+			break;
+#ifdef PWM_TYPE_O			
+		case PWM_TYPE_O:
+			ast_pwm_tacho_write(ast_pwm_tacho,
+			ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0) | enable, 
+			AST_PTCR_TYPEO_CTRL0);
+
+			break;
+#endif			
+		default:
+			printk("ERROR type !! \n");
+			break;
+	}	
+}
+
+static u32
+ast_get_tacho_type_limit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
+{
+	switch(pwm_type) {
+		case PWM_TYPE_M:
+			return (FAN_LIMIT_MASK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_LIMIT));
+			break;
+		case PWM_TYPE_N:
+			return (FAN_LIMIT_MASK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_LIMIT));
+			break;
+#ifdef PWM_TYPE_O			
+		case PWM_TYPE_O:
+			return (FAN_LIMIT_MASK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_LIMIT));
+			break;
+#endif			
+		default:
+			printk("ERROR type !! \n");
+			break;
+	}	
+}
+
+static void
+ast_set_tacho_type_limit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type,u32 limit)
+{
+	if(limit > FAN_LIMIT_MASK)
+		return;
+
+	switch(pwm_type) {
+		case PWM_TYPE_M:
+			ast_pwm_tacho_write(ast_pwm_tacho, limit, AST_PTCR_TYPEM_LIMIT);
+			break;
+		case PWM_TYPE_N:
+			ast_pwm_tacho_write(ast_pwm_tacho, limit, AST_PTCR_TYPEN_LIMIT);
+			break;
+#ifdef PWM_TYPE_O			
+		case PWM_TYPE_O:
+			ast_pwm_tacho_write(ast_pwm_tacho, limit, AST_PTCR_TYPEO_LIMIT);
+			break;
+#endif			
+		default:
+			printk("ERROR type !! \n");
+			break;
+	}	
+	
+}
+
+static u8
+ast_get_tacho_alarm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch)
+{
+	//tacho source
+	if(	ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_INTR_CTRL) & INTR_CTRL_EN_NUM(tacho_ch))
+		return 1;
+	else
+		return 0;
+}
+
+static void
+ast_set_tacho_alarm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch, u8 enable)
+{
+	//tacho source 
+	if(enable == 1)
+		ast_pwm_tacho_write(ast_pwm_tacho,
+			ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_INTR_CTRL) | INTR_CTRL_EN_NUM(tacho_ch), 
+			AST_PTCR_INTR_CTRL);
+	else
+		ast_pwm_tacho_write(ast_pwm_tacho,
+			ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_INTR_CTRL) & ~(INTR_CTRL_EN_NUM(tacho_ch)), 
+			AST_PTCR_INTR_CTRL);
+}
+
+static u8
+ast_get_tacho_alarm(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch)
+{
+	//tacho source 
+	if(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_INTR_STS) & INTR_CTRL_NUM(tacho_ch))
+		return 1;
+	else
+		return 0;
+}
+
+static u8 
+ast_get_tacho_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch)
+{
+	if(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_FAN_NUM_EN(tacho_ch))
+		return 1;
+	else 
+		return 0;
+}
+
+static void 
+ast_set_tacho_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch, u8 enable)
+{
+	//tacho number enable
+	if(enable)
+		ast_pwm_tacho_write(ast_pwm_tacho,
+			ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_FAN_NUM_EN(tacho_ch),
+			AST_PTCR_CTRL);
+	else
+		ast_pwm_tacho_write(ast_pwm_tacho,
+			ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~(AST_PTCR_CTRL_FAN_NUM_EN(tacho_ch)),
+			AST_PTCR_CTRL);		
+}
+
+static u8
+ast_get_tacho_source(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch)
+{
+    u32 tmp1, tmp2;
+
+	//tacho source 
+    tmp1 = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TACH_SOURCE);
+	tmp1 &= TACH_PWM_SOURCE_MASK_BIT01(tacho_ch);
+	tmp1 = tmp1 >> (TACH_PWM_SOURCE_BIT01(tacho_ch));
+	
+	tmp2 = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TACH_SOURCE_EXT);
+    tmp2 &= TACH_PWM_SOURCE_MASK_BIT2(tacho_ch);
+	tmp2 = tmp2 >> (TACH_PWM_SOURCE_BIT2(tacho_ch));
+	tmp2 = tmp2 << 2;
+
+	return (tmp2 | tmp1);
+}
+
+static void
+ast_set_tacho_source(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch, u8 tacho_source)
+{
+    u32 tmp1, tmp2;
+	if(tacho_source > 7)
+		return;
+	
+	//tacho source 
+    tmp1 = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TACH_SOURCE);
+	tmp1 &= ~(TACH_PWM_SOURCE_MASK_BIT01(tacho_ch));
+	tmp1 |= ((tacho_source &0x3) << (TACH_PWM_SOURCE_BIT01(tacho_ch)));
+	
+	tmp2 = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TACH_SOURCE_EXT);
+    tmp2 &= ~(TACH_PWM_SOURCE_MASK_BIT2(tacho_ch));
+	tmp2 |= (((tacho_source &0x4)>>2) << (TACH_PWM_SOURCE_BIT2(tacho_ch)));
+
+	ast_pwm_tacho_write(ast_pwm_tacho, tmp1, AST_PTCR_TACH_SOURCE);
+	ast_pwm_tacho_write(ast_pwm_tacho, tmp2, AST_PTCR_TACH_SOURCE_EXT);
+
+}
+
+static u32
+ast_get_tacho_rpm(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch)
+{
+    u32 raw_data, rpm, tacho_clk_div, clk_source, timeout=0;
+	u8 tacho_source, pwm_type,tacho_type_en;
+
+	if(!(ast_get_tacho_en(ast_pwm_tacho,tacho_ch)))
+		return 0;
+	
+	//write 0 
+	ast_pwm_tacho_write(ast_pwm_tacho, 0, AST_PTCR_TRIGGER);
+
+	//write 1
+	ast_pwm_tacho_write(ast_pwm_tacho, 0x1 << tacho_ch, AST_PTCR_TRIGGER);
+
+	tacho_source = ast_get_tacho_source(ast_pwm_tacho, tacho_ch);
+	pwm_type = ast_get_pwm_type(ast_pwm_tacho, tacho_source);
+	tacho_type_en = ast_get_tacho_type_en(ast_pwm_tacho, pwm_type);
+	
+//	printk("source: %d,type: %d,en: %d \n",tacho_source,pwm_type,tacho_type_en);
+
+	//check pwm_type and get clock division
+	if(!tacho_type_en)
+		return 0;
+
+	//Wait ready
+	while(!(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_RESULT) & (0x1 << RESULT_STATUS))) {
+		timeout++;
+		if(timeout > 25)
+			return 0;
+	};
+
+	raw_data = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_RESULT)& RESULT_VALUE_MASK;
+	tacho_clk_div = ast_get_tacho_type_division(ast_pwm_tacho, pwm_type);
+
+//	printk("raw div = %d \n",tacho_clk_div);
+	
+	tacho_clk_div = 0x4 << (tacho_clk_div*2);
+//	printk("raw div = %d \n",tacho_clk_div);
+
+	//TODO 166
+	if(AST_PTCR_CTRL_CLK_MCLK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL))
+		clk_source = 166*1000*1000;
+	else
+		clk_source = 24*1000*1000;
+	
+	printk("raw_data %d, clk_source %d, tacho_clk_div %d \n",raw_data, clk_source, tacho_clk_div);
+	rpm = (clk_source * 60) / (2 * raw_data * tacho_clk_div);
+	
+    return rpm; 
+}
+
+static u8 
+ast_get_pwm_clock_division_h(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
+{
+	u8 tmp=0;
+
+	switch (pwm_type) {
+	case PWM_TYPE_M:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & AST_PTCR_CLK_CTRL_TYPEM_H_MASK) >> AST_PTCR_CLK_CTRL_TYPEM_H;
+		break;
+	case PWM_TYPE_N:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & AST_PTCR_CLK_CTRL_TYPEN_H_MASK) >> AST_PTCR_CLK_CTRL_TYPEN_H;
+		break;
+#ifdef PWM_TYPE_O
+	case PWM_TYPE_O:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_EXT_CTRL) & AST_PTCR_CLK_CTRL_TYPEO_H_MASK) >> AST_PTCR_CLK_CTRL_TYPEO_H;		
+		break;
+#endif		
+	default:
+		printk("error channel ast_get_pwm_clock_division_h %d \n",pwm_type);
+		break;
+	}
+	return tmp;
+}
+
+static void 
+ast_set_pwm_clock_division_h(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type, u8 div_high)
+{
+	if(div_high > 0xf)
+		return;
+	switch (pwm_type) {
+	case PWM_TYPE_M:
+	 ast_pwm_tacho_write(ast_pwm_tacho,
+	 	(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEM_H_MASK) | (div_high << AST_PTCR_CLK_CTRL_TYPEM_H),
+	 	AST_PTCR_CLK_CTRL);
+	 break;
+	case PWM_TYPE_N:
+	ast_pwm_tacho_write(ast_pwm_tacho,
+	 	(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEN_H_MASK) | (div_high << AST_PTCR_CLK_CTRL_TYPEN_H),
+	 	AST_PTCR_CLK_CTRL);
+	 break;
+#ifdef PWM_TYPE_O
+	 case PWM_TYPE_O:
+	 ast_pwm_tacho_write(ast_pwm_tacho,
+		 (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_EXT_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEO_H_MASK) | (div_high << AST_PTCR_CLK_CTRL_TYPEO_H),
+		 AST_PTCR_CLK_EXT_CTRL);
+	  break;
+#endif			 
+	default:
+	 printk("error channel ast_get_pwm_type %d \n",pwm_type);
+	 break;
+	}
+
+}
+
+static u8 
+ast_get_pwm_clock_division_l(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
+{
+	u8 tmp=0;
+
+	switch (pwm_type) {
+	case PWM_TYPE_M:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & AST_PTCR_CLK_CTRL_TYPEM_L_MASK) >> AST_PTCR_CLK_CTRL_TYPEM_L;
+		break;
+	case PWM_TYPE_N:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & AST_PTCR_CLK_CTRL_TYPEN_L_MASK) >> AST_PTCR_CLK_CTRL_TYPEN_L;
+		break;
+#ifdef PWM_TYPE_O		
+	case PWM_TYPE_O:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_EXT_CTRL) & AST_PTCR_CLK_CTRL_TYPEO_L_MASK) >> AST_PTCR_CLK_CTRL_TYPEO_L;
+		break;
+#endif		
+	default:
+		printk("error channel ast_get_pwm_clock_division_l %d \n",pwm_type);
+		break;
+	}
+	return tmp;
+}
+
+static void 
+ast_set_pwm_clock_division_l(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type, u8 div_low)
+{
+	if(div_low> 0xf)
+		return;
+	switch (pwm_type) {
+	case PWM_TYPE_M:
+	 ast_pwm_tacho_write(ast_pwm_tacho,
+	 	(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEM_L_MASK) | (div_low << AST_PTCR_CLK_CTRL_TYPEM_L),
+	 	AST_PTCR_CLK_CTRL);
+	 break;
+	case PWM_TYPE_N:
+	ast_pwm_tacho_write(ast_pwm_tacho,
+	 	(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEN_L_MASK) | (div_low << AST_PTCR_CLK_CTRL_TYPEN_L),
+	 	AST_PTCR_CLK_CTRL);
+	 break;
+#ifdef PWM_TYPE_O			 
+	case PWM_TYPE_O:
+	ast_pwm_tacho_write(ast_pwm_tacho,
+		(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_EXT_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEO_L_MASK) | (div_low << AST_PTCR_CLK_CTRL_TYPEO_L),
+	 	AST_PTCR_CLK_EXT_CTRL);
+	 break;
+#endif	 
+	default:
+	 printk("error channel ast_get_pwm_type %d \n",pwm_type);
+	 break;
+	}
+}
+
+static u8 
+ast_get_pwm_clock_unit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
+{
+    u8 tmp=0;
+
+    switch (pwm_type) {
+	case PWM_TYPE_M:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & AST_PTCR_CLK_CTRL_TYPEM_UNIT_MASK) >> AST_PTCR_CLK_CTRL_TYPEM_UNIT;
+		break;
+	case PWM_TYPE_N:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & AST_PTCR_CLK_CTRL_TYPEN_UNIT_MASK) >> AST_PTCR_CLK_CTRL_TYPEN_UNIT;
+		break;
+#ifdef PWM_TYPE_O			 		
+	case PWM_TYPE_O:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_EXT_CTRL) & AST_PTCR_CLK_CTRL_TYPEO_UNIT_MASK) >> AST_PTCR_CLK_CTRL_TYPEO_UNIT;
+		break;
+#endif		
+	default:
+		printk("error channel ast_get_pwm_clock_unit %d \n",pwm_type);
+		break;
+    }
+	return tmp;
+}
+
+static void 
+ast_set_pwm_clock_unit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type, u8 unit)
+{
+	if(unit > 0xff)
+		return;
+	switch (pwm_type) {
+	case PWM_TYPE_M:
+	 ast_pwm_tacho_write(ast_pwm_tacho,
+	 	(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEM_UNIT_MASK) | (unit << AST_PTCR_CLK_CTRL_TYPEM_UNIT),
+	 	AST_PTCR_CLK_CTRL);
+	 break;
+	case PWM_TYPE_N:
+	ast_pwm_tacho_write(ast_pwm_tacho,
+	 	(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEN_UNIT_MASK) | (unit << AST_PTCR_CLK_CTRL_TYPEN_UNIT),
+	 	AST_PTCR_CLK_CTRL);
+	 break;
+#ifdef PWM_TYPE_O			 	 
+	case PWM_TYPE_O:
+	ast_pwm_tacho_write(ast_pwm_tacho,
+		(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_EXT_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEO_UNIT_MASK) | (unit << AST_PTCR_CLK_CTRL_TYPEO_UNIT),
+	 	AST_PTCR_CLK_EXT_CTRL);
+	 break;
+#endif	 
+	default:
+	 printk("error channel ast_get_pwm_type %d \n",pwm_type);
+	 break;
+	}
+}
+
+static u32
+ast_get_pwm_clock(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
+{
+	u32 unit, div_low, div_high, clk_source;
+	
+	unit = ast_get_pwm_clock_unit(ast_pwm_tacho,pwm_type);		
+
+	div_high = ast_get_pwm_clock_division_h(ast_pwm_tacho,pwm_type);
+	div_high = (0x1<<div_high);
+
+	div_low = ast_get_pwm_clock_division_l(ast_pwm_tacho,pwm_type); 
+	if(div_low == 0)
+		div_low = 1;
+	else
+		div_low = div_low*2;
+	//TODO 266
+
+	if(AST_PTCR_CTRL_CLK_MCLK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL))
+			clk_source = ast_pwm_tacho->ast_pwm_data->get_pwm_clock();
+		else
+			clk_source = 24*1000*1000;
+
+//	printk("%d, %d, %d, %d \n",clk_source,div_high,div_low,unit);
+	return (clk_source/(div_high*div_low*(unit+1)));
+}
+
+static u8 
+ast_get_pwm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch)
+{
+    u8 tmp=0;
+
+    switch (pwm_ch) {
+	case PWMA:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWA_EN) >> AST_PTCR_CTRL_PMWA;
+		break;
+	case PWMB:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWB_EN) >> AST_PTCR_CTRL_PMWB;
+		break;
+	case PWMC:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWC_EN) >> AST_PTCR_CTRL_PMWC;
+		break;
+	case PWMD:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWD_EN) >> AST_PTCR_CTRL_PMWD;
+		break;
+	case PWME:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWE_EN) >> AST_PTCR_CTRL_PMWE;
+		break;
+	case PWMF:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWF_EN) >> AST_PTCR_CTRL_PMWF;
+		break;
+	case PWMG:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWG_EN) >> AST_PTCR_CTRL_PMWG;
+		break;
+	case PWMH:
+		tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWH_EN) >> AST_PTCR_CTRL_PMWH;
+		break;
+	default:
+		printk("error channel ast_get_pwm_type %d \n",pwm_ch);
+		break;
+    }
+
+	return tmp;
+
+}
+
+static void 
+ast_set_pwm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch, u8 enable)
+{
+    switch (pwm_ch) {
+	case PWMA:
+		if(enable)
+			ast_pwm_tacho_write(ast_pwm_tacho,
+					ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWA_EN, 
+					AST_PTCR_CTRL);
+		else
+			ast_pwm_tacho_write(ast_pwm_tacho,
+					ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWA_EN, 
+					AST_PTCR_CTRL);
+			
+		break;
+	case PWMB:
+		if(enable)		
+			ast_pwm_tacho_write(ast_pwm_tacho,	
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWB_EN),
+					AST_PTCR_CTRL);
+		else
+			ast_pwm_tacho_write(ast_pwm_tacho,	
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWB_EN),
+					AST_PTCR_CTRL);			
+		break;
+	case PWMC:
+		if(enable)
+			ast_pwm_tacho_write(ast_pwm_tacho,	
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWC_EN),
+					AST_PTCR_CTRL);
+		else
+			ast_pwm_tacho_write(ast_pwm_tacho,	
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWC_EN),
+					AST_PTCR_CTRL);
+			
+		break;
+	case PWMD:
+		if(enable)
+			ast_pwm_tacho_write(ast_pwm_tacho,	
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWD_EN),
+					AST_PTCR_CTRL);
+		else
+			ast_pwm_tacho_write(ast_pwm_tacho,	
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWD_EN),
+					AST_PTCR_CTRL);
+			
+		break;
+	case PWME:
+		if(enable)
+			ast_pwm_tacho_write(ast_pwm_tacho,
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWE_EN),
+					AST_PTCR_CTRL_EXT);
+		else
+			ast_pwm_tacho_write(ast_pwm_tacho,
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWE_EN),
+					AST_PTCR_CTRL_EXT);
+			
+		break;
+	case PWMF:
+		if(enable)
+			ast_pwm_tacho_write(ast_pwm_tacho,
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWF_EN),
+					AST_PTCR_CTRL_EXT);
+		else
+			ast_pwm_tacho_write(ast_pwm_tacho,
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWF_EN),
+					AST_PTCR_CTRL_EXT);
+			
+		break;
+	case PWMG:
+		if(enable)
+			ast_pwm_tacho_write(ast_pwm_tacho,
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWG_EN),
+					AST_PTCR_CTRL_EXT);
+		else
+			ast_pwm_tacho_write(ast_pwm_tacho,
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWG_EN),
+					AST_PTCR_CTRL_EXT);
+			
+		break;
+	case PWMH:
+		if(enable)
+			ast_pwm_tacho_write(ast_pwm_tacho,
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWH_EN),
+					AST_PTCR_CTRL_EXT);
+		else
+			ast_pwm_tacho_write(ast_pwm_tacho,
+					(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWH_EN),
+					AST_PTCR_CTRL_EXT);
+
+		break;
+	default:
+		printk("error channel ast_get_pwm_type %d \n",pwm_ch);
+		break;
+    }
+}
+
+static u8
+ast_get_pwm_type(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch)
+{
+    u8 tmp=0;
+
+    switch (pwm_ch) {
+	case PWMA:
+		tmp = AST_PTCR_CTRL_GET_PWMA_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL));
+		break;
+	case PWMB:
+		tmp = AST_PTCR_CTRL_GET_PWMB_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL));
+		break;
+	case PWMC:
+		tmp = AST_PTCR_CTRL_GET_PWMC_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL));
+		break;
+	case PWMD:
+		tmp = AST_PTCR_CTRL_GET_PWMD_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL));
+		break;
+	case PWME:
+		tmp = AST_PTCR_CTRL_GET_PWME_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT));
+		break;
+	case PWMF:
+		tmp = AST_PTCR_CTRL_GET_PWMF_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT));
+		break;
+	case PWMG:
+		tmp = AST_PTCR_CTRL_GET_PWMG_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT));
+		break;
+	case PWMH:
+		tmp = AST_PTCR_CTRL_GET_PWMH_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT));
+		break;
+	default:
+		printk("error channel ast_get_pwm_type %d \n",pwm_ch);
+		break;
+    }
+
+	return tmp;
+}
+
+static void
+ast_set_pwm_type(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch, u8 type)
+{
+    u32 tmp1,tmp2;
+
+	if(type > 0x2)
+		return;
+
+	tmp1 = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL);
+	tmp2 = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT);
+
+    switch (pwm_ch) {
+	case PWMA:
+		tmp1 &= ~AST_PTCR_CTRL_SET_PWMA_TYPE_MASK;
+		tmp1 |= AST_PTCR_CTRL_SET_PWMA_TYPE(type);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp1, AST_PTCR_CTRL);
+		break;
+	case PWMB:
+		tmp1 &= ~AST_PTCR_CTRL_SET_PWMB_TYPE_MASK;
+		tmp1 |= AST_PTCR_CTRL_SET_PWMB_TYPE(type);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp1, AST_PTCR_CTRL);
+		break;
+	case PWMC:
+		tmp1 &= ~AST_PTCR_CTRL_SET_PWMC_TYPE_MASK;
+		tmp1 |= AST_PTCR_CTRL_SET_PWMC_TYPE(type);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp1, AST_PTCR_CTRL);
+		break;
+	case PWMD:
+		tmp1 &= ~AST_PTCR_CTRL_SET_PWMD_TYPE_MASK;
+		tmp1 |= AST_PTCR_CTRL_SET_PWMD_TYPE(type);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp1, AST_PTCR_CTRL);
+		break;
+	case PWME:
+		tmp2 &= ~AST_PTCR_CTRL_SET_PWME_TYPE_MASK;
+		tmp2 |= AST_PTCR_CTRL_SET_PWME_TYPE(type);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp2, AST_PTCR_CTRL_EXT);
+		break;
+	case PWMF:
+		tmp2 &= ~AST_PTCR_CTRL_SET_PWMF_TYPE_MASK;
+		tmp2 |= AST_PTCR_CTRL_SET_PWMF_TYPE(type);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp2, AST_PTCR_CTRL_EXT);
+		break;
+	case PWMG:
+		tmp2 &= ~AST_PTCR_CTRL_SET_PWMG_TYPE_MASK;
+		tmp2 |= AST_PTCR_CTRL_SET_PWMG_TYPE(type);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp2, AST_PTCR_CTRL_EXT);
+		break;
+	case PWMH:
+		tmp2 &= ~AST_PTCR_CTRL_SET_PWMH_TYPE_MASK;
+		tmp2 |= AST_PTCR_CTRL_SET_PWMH_TYPE(type);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp2, AST_PTCR_CTRL_EXT);
+		break;
+	default:
+		printk("error channel %d \n",pwm_ch);
+		break;
+    }
+}
+
+// PWM DUTY 
+static u8
+ast_get_pwm_duty_rising(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch)
+{
+	u32 tmp=0;
+    switch (pwm_ch) {
+	case PWMA:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
+		tmp &= DUTY_CTRL0_PWMA_RISE_POINT_MASK;
+		break;
+	case PWMB:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
+		tmp &= DUTY_CTRL0_PWMB_RISE_POINT_MASK;
+		tmp = (tmp >> DUTY_CTRL0_PWMB_RISE_POINT);
+		break;
+	case PWMC:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
+		tmp &= DUTY_CTRL1_PWMC_RISE_POINT_MASK;
+		break;
+	case PWMD:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
+		tmp &= DUTY_CTRL1_PWMD_RISE_POINT_MASK;
+		tmp = (tmp >> DUTY_CTRL1_PWMD_RISE_POINT);
+		break;
+	case PWME:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
+		tmp &= DUTY_CTRL2_PWME_RISE_POINT_MASK;
+		break;
+	case PWMF:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
+		tmp &= DUTY_CTRL2_PWMF_RISE_POINT_MASK;
+		tmp = (tmp >> DUTY_CTRL2_PWMF_RISE_POINT);
+		break;
+	case PWMG:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
+		tmp &= DUTY_CTRL3_PWMG_RISE_POINT_MASK;
+		break;
+	case PWMH:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
+		tmp &= DUTY_CTRL3_PWMH_RISE_POINT_MASK;
+		tmp = (tmp >> DUTY_CTRL3_PWMH_RISE_POINT);
+		break;			
+	default:
+	    printk("error pwm channel %d with duty R \n",pwm_ch);
+		break;
+    }
+	
+	return tmp;
+}
+
+static void
+ast_set_pwm_duty_rising(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch, u8 rising)
+{
+	u32 tmp=0;
+	u32 pwm_type = ast_get_pwm_type(ast_pwm_tacho,pwm_ch);
+	
+	if((rising > 0xff) || (rising > ast_get_pwm_clock_unit(ast_pwm_tacho,pwm_type)))
+		return;
+	
+    switch (pwm_ch) {
+	case PWMA:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
+		tmp &= ~DUTY_CTRL0_PWMA_RISE_POINT_MASK;
+		tmp |= rising;
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY0_CTRL);
+		break;
+	case PWMB:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
+		tmp &= ~DUTY_CTRL0_PWMB_RISE_POINT_MASK;
+		tmp |= (rising << DUTY_CTRL0_PWMB_RISE_POINT);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY0_CTRL);
+		break;
+	case PWMC:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
+		tmp &= ~DUTY_CTRL1_PWMC_RISE_POINT_MASK;
+		tmp |= rising;
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY1_CTRL);
+		break;
+	case PWMD:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
+		tmp &= ~DUTY_CTRL1_PWMD_RISE_POINT_MASK;
+		tmp |= (rising << DUTY_CTRL1_PWMD_RISE_POINT);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY1_CTRL);
+		break;
+	case PWME:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
+		tmp &= ~DUTY_CTRL2_PWME_RISE_POINT_MASK;
+		tmp |= rising;
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY2_CTRL);
+		break;
+	case PWMF:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
+		tmp &= ~DUTY_CTRL2_PWMF_RISE_POINT_MASK;
+		tmp |= (rising << DUTY_CTRL2_PWMF_RISE_POINT);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY2_CTRL);
+		break;
+	case PWMG:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
+		tmp &= ~DUTY_CTRL3_PWMG_RISE_POINT_MASK;
+		tmp |= rising;
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY3_CTRL);
+		break;
+	case PWMH:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
+		tmp &= ~DUTY_CTRL3_PWMH_RISE_POINT_MASK;
+		tmp |= (rising << DUTY_CTRL3_PWMH_RISE_POINT);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY3_CTRL);
+		break;			
+
+	default:
+	    printk("error pwm channel %d with duty \n",pwm_ch);
+		break;
+    }
+}
+
+static u8
+ast_get_pwm_duty_falling(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch)
+{
+	u32 tmp=0;
+    switch (pwm_ch) {
+	case PWMA:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
+		tmp &= DUTY_CTRL0_PWMA_FALL_POINT_MASK;
+		tmp = (tmp >> DUTY_CTRL0_PWMA_FALL_POINT);
+		break;
+	case PWMB:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
+		tmp &= DUTY_CTRL0_PWMB_FALL_POINT_MASK;
+		tmp = (tmp >> DUTY_CTRL0_PWMB_FALL_POINT);
+		break;
+	case PWMC:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
+		tmp &= DUTY_CTRL1_PWMC_FALL_POINT_MASK;
+		tmp = (tmp >> DUTY_CTRL1_PWMC_FALL_POINT);
+		break;
+	case PWMD:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
+		tmp &= DUTY_CTRL1_PWMD_FALL_POINT_MASK;
+		tmp = (tmp >> DUTY_CTRL1_PWMD_FALL_POINT);
+		break;
+	case PWME:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
+		tmp &= DUTY_CTRL2_PWME_FALL_POINT_MASK;
+		tmp = (tmp >> DUTY_CTRL2_PWME_FALL_POINT);
+		break;
+	case PWMF:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
+		tmp &= DUTY_CTRL2_PWMF_FALL_POINT_MASK;
+		tmp = (tmp >> DUTY_CTRL2_PWMF_FALL_POINT);
+		break;
+	case PWMG:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
+		tmp &= DUTY_CTRL3_PWMG_FALL_POINT_MASK;
+		tmp = (tmp >> DUTY_CTRL3_PWMG_FALL_POINT);
+		break;
+	case PWMH:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
+		tmp &= DUTY_CTRL3_PWMH_FALL_POINT_MASK;
+		tmp = (tmp >> DUTY_CTRL3_PWMH_FALL_POINT);
+		break;			
+
+	default:
+	    printk("error pwm channel %d with duty F \n",pwm_ch);
+		break;
+    }
+	
+	return tmp;
+}
+
+static void
+ast_set_pwm_duty_falling(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch, u8 falling)
+{
+	u32 tmp =0;
+	u32 pwm_type = ast_get_pwm_type(ast_pwm_tacho,pwm_ch);
+	
+	if((falling > 0xff) || (falling > ast_get_pwm_clock_unit(ast_pwm_tacho,pwm_type)))
+		return;
+	
+    switch (pwm_ch) {
+	case PWMA:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
+		tmp &= ~DUTY_CTRL0_PWMA_FALL_POINT_MASK;
+		tmp |= (falling << DUTY_CTRL0_PWMA_FALL_POINT);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY0_CTRL);
+		break;
+	case PWMB:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
+		tmp &= ~DUTY_CTRL0_PWMB_FALL_POINT_MASK;
+		tmp |= (falling << DUTY_CTRL0_PWMB_FALL_POINT);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY0_CTRL);
+		break;
+	case PWMC:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
+		tmp &= ~DUTY_CTRL1_PWMC_FALL_POINT_MASK;
+		tmp |= (falling << DUTY_CTRL1_PWMC_FALL_POINT);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY1_CTRL);
+		break;
+	case PWMD:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
+		tmp &= ~DUTY_CTRL1_PWMD_FALL_POINT_MASK;
+		tmp |= (falling << DUTY_CTRL1_PWMD_FALL_POINT);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY1_CTRL);
+		break;
+	case PWME:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
+		tmp &= ~DUTY_CTRL2_PWME_FALL_POINT_MASK;
+		tmp |= (falling << DUTY_CTRL2_PWME_FALL_POINT);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY2_CTRL);
+		break;
+	case PWMF:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
+		tmp &= ~DUTY_CTRL2_PWMF_FALL_POINT_MASK;
+		tmp |= (falling << DUTY_CTRL2_PWMF_FALL_POINT);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY2_CTRL);
+		break;
+	case PWMG:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
+		tmp &= ~DUTY_CTRL3_PWMG_FALL_POINT_MASK;
+		tmp |= (falling << DUTY_CTRL3_PWMG_FALL_POINT);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY3_CTRL);
+		break;
+	case PWMH:
+		tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
+		tmp &= ~DUTY_CTRL3_PWMH_FALL_POINT_MASK;
+		tmp |= (falling << DUTY_CTRL3_PWMH_FALL_POINT);
+		ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY3_CTRL);
+		break;			
+
+	default:
+	    printk("error pwm channel %d with duty \n",pwm_ch);
+		break;
+    }
+
+}
+
+/*PWM M/N/O Type sysfs*/
+/* 
+ * Macro defining SENSOR_DEVICE_ATTR for a pwm sysfs entries.
+ *  0 - show/store unit
+ *  1 - show/store division_l
+ *  2 - show/store division_h 
+ */
+
+static ssize_t 
+ast_show_pwm_type_clock(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+{
+	struct sensor_device_attribute_2 *sensor_attr =
+						to_sensor_dev_attr_2(attr);
+
+
+	//sensor_attr->index : M/N/O#
+	//sensor_attr->nr : attr#
+	switch(sensor_attr->nr) 
+	{
+		case 0: //unit : 0~256
+			return sprintf(sysfsbuf, "%d (0~255)\n", ast_get_pwm_clock_unit(ast_pwm_tacho,sensor_attr->index));
+			break;
+		case 1: //division_l
+			return sprintf(sysfsbuf, "%d (0~15) \n", ast_get_pwm_clock_division_l(ast_pwm_tacho,sensor_attr->index));
+			break;
+		case 2: //division_h
+			return sprintf(sysfsbuf, "%d (0~15) \n", ast_get_pwm_clock_division_h(ast_pwm_tacho,sensor_attr->index));
+			
+			break;			
+		case 3: //expect clock
+
+			return sprintf(sysfsbuf, "%d  \n", ast_get_pwm_clock(ast_pwm_tacho,sensor_attr->index));
+			
+			break;			
+
+		default:
+			return -EINVAL;
+			break;
+	}
+
+	return sprintf(sysfsbuf, "%d : %d\n", sensor_attr->nr,sensor_attr->index);
+
+
+}
+
+static ssize_t 
+ast_store_pwm_type_clock(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
+{
+	u32 input_val;
+	struct sensor_device_attribute_2 *sensor_attr =
+						to_sensor_dev_attr_2(attr);
+
+	input_val = simple_strtoul(sysfsbuf, NULL, 10);
+
+	switch(sensor_attr->nr) 
+	{
+		case 0: //unit : 0~256
+			ast_set_pwm_clock_unit(ast_pwm_tacho, sensor_attr->index, input_val);
+			break;
+		case 1: //division_l
+			ast_set_pwm_clock_division_l(ast_pwm_tacho, sensor_attr->index, input_val);
+			break;
+		case 2: //division_h
+			ast_set_pwm_clock_division_h(ast_pwm_tacho, sensor_attr->index, input_val);
+			break;			
+		default:
+			return -EINVAL;
+			break;
+	}
+
+	return count;
+}
+
+/* attr
+ *  0 - show/store enable
+ *  1 - show/store type
+ *  2 - show/store falling
+ *  3 - show/store rising */
+static ssize_t 
+ast_show_pwm_speed(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+{
+	struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+
+	//sensor_attr->index : pwm_ch#
+	//sensor_attr->nr : attr#
+	switch(sensor_attr->nr) 
+	{
+		case 0: //enable, disable
+			return sprintf(sysfsbuf, "%d : %s\n", ast_get_pwm_en(ast_pwm_tacho,sensor_attr->index),ast_get_pwm_en(ast_pwm_tacho,sensor_attr->index) ? "Enable":"Disable");
+			break;
+		case 1: //pwm type M/N/O
+			return sprintf(sysfsbuf, "%d (0:M/1:N/2:O)\n",ast_get_pwm_type(ast_pwm_tacho, sensor_attr->index));
+			break;
+		case 2: //rising
+			return sprintf(sysfsbuf, "%x : unit limit (0~%d)\n",ast_get_pwm_duty_rising(ast_pwm_tacho, sensor_attr->index),
+						ast_get_pwm_clock_unit(ast_pwm_tacho, ast_get_pwm_type(ast_pwm_tacho, sensor_attr->index)));
+			break;						
+		case 3: //falling
+			return sprintf(sysfsbuf, "%x : unit limit (0~%d)\n",ast_get_pwm_duty_falling(ast_pwm_tacho, sensor_attr->index),
+						ast_get_pwm_clock_unit(ast_pwm_tacho, ast_get_pwm_type(ast_pwm_tacho, sensor_attr->index)));			
+			break;			
+		default:
+			return -EINVAL;
+			break;
+	}
+}
+
+static ssize_t 
+ast_store_pwm_speed(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
+{
+	u32 input_val;
+	struct sensor_device_attribute_2 *sensor_attr =
+						to_sensor_dev_attr_2(attr);
+
+	input_val = simple_strtoul(sysfsbuf, NULL, 10);
+
+	//sensor_attr->index : pwm_ch#
+	//sensor_attr->nr : attr#
+	switch(sensor_attr->nr) 
+	{
+		case 0: //enable, disable
+			ast_set_pwm_en(ast_pwm_tacho, sensor_attr->index, input_val);
+			break;
+		case 1: //pwm type M/N/O
+			ast_set_pwm_type(ast_pwm_tacho, sensor_attr->index, input_val);
+			break;
+		case 2: //rising
+			ast_set_pwm_duty_rising(ast_pwm_tacho, sensor_attr->index, input_val);
+			break;			
+		case 3: //falling
+			ast_set_pwm_duty_falling(ast_pwm_tacho, sensor_attr->index, input_val);
+			break;			
+		default:
+			return -EINVAL;
+			break;
+	}
+
+	return count;
+}
+
+/* Fan Type  */
+/* Fan M/N/O Type sysfs 
+ * Macro defining SENSOR_DEVICE_ATTR for a pwm sysfs entries.
+ *  0 - show/store enable
+ *  1 - show/store mode
+ *  2 - show/store unit
+ *  3 - show/store division
+ *  4 - show/store limit
+ */
+
+static ssize_t 
+ast_show_tacho_type(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+{
+	struct sensor_device_attribute_2 *sensor_attr =
+						to_sensor_dev_attr_2(attr);
+
+	//sensor_attr->index : M/N/O
+	//sensor_attr->nr : attr#
+	switch(sensor_attr->nr) 
+	{
+		case 0: //enable, disable
+			return sprintf(sysfsbuf, "%d : %s\n", ast_get_tacho_type_en(ast_pwm_tacho,sensor_attr->index),ast_get_tacho_type_en(ast_pwm_tacho,sensor_attr->index) ? "Enable":"Disable");
+			break;
+		case 1: //fan tacho mode
+			if(ast_get_tacho_type_mode(ast_pwm_tacho, sensor_attr->index) == FALL_EDGE)
+				return sprintf(sysfsbuf, "0: falling\n");
+			else if(ast_get_tacho_type_mode(ast_pwm_tacho, sensor_attr->index) == RISE_EDGE)
+				return sprintf(sysfsbuf, "1: rising\n");
+			else if (ast_get_tacho_type_mode(ast_pwm_tacho, sensor_attr->index) == BOTH_EDGE) 
+				return sprintf(sysfsbuf, "2: both\n");
+			else 
+				return sprintf(sysfsbuf, "3: unknown\n");
+			break;
+		case 2: //unit
+			return sprintf(sysfsbuf, "%d (0~65535)\n",ast_get_tacho_type_unit(ast_pwm_tacho, sensor_attr->index));
+			
+			break;			
+		case 3: //division
+			return sprintf(sysfsbuf, "%d (0~7) \n",ast_get_tacho_type_division(ast_pwm_tacho, sensor_attr->index));
+			break;			
+		case 4: //limit
+			return sprintf(sysfsbuf, "%d (0~1048575)\n",ast_get_tacho_type_limit(ast_pwm_tacho, sensor_attr->index));
+			break;			
+		case 5: //measure period
+			return sprintf(sysfsbuf, "%d \n",ast_get_tacho_measure_period(ast_pwm_tacho, sensor_attr->index));
+			break;			
+		default:
+			return -EINVAL;
+			break;
+	}
+}
+
+static ssize_t 
+ast_store_tacho_type(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
+{
+	u32 input_val;
+	struct sensor_device_attribute_2 *sensor_attr =
+						to_sensor_dev_attr_2(attr);
+
+	input_val = simple_strtoul(sysfsbuf, NULL, 10);
+
+	//sensor_attr->index : pwm_ch#
+	//sensor_attr->nr : attr#
+	switch(sensor_attr->nr) 
+	{
+		case 0: //enable, disable
+			ast_set_tacho_type_en(ast_pwm_tacho,sensor_attr->index, input_val);
+			break;
+		case 1: //fan tacho mode
+			ast_set_tacho_type_mode(ast_pwm_tacho, sensor_attr->index, input_val);
+			break;
+		case 2: //unit
+			ast_set_tacho_type_unit(ast_pwm_tacho, sensor_attr->index, input_val);
+			break;			
+		case 3: //division
+			ast_set_tacho_type_division(ast_pwm_tacho, sensor_attr->index, input_val);
+			break;			
+		case 4: //limit
+			ast_set_tacho_type_limit(ast_pwm_tacho, sensor_attr->index, input_val);
+			break;			
+		default:
+			return -EINVAL;
+			break;
+	}
+	return count;
+
+}
+
+/* fan detect */
+/* FAN sysfs
+ * Macro defining SENSOR_DEVICE_ATTR for a tacho sysfs entries.
+ *  - show/store enable
+ *  - show/store source
+ *  - show/store rpm
+ *  - show/store alarm
+ *  - show/store alarm_en 
+*/
+static ssize_t 
+ast_show_tacho_speed(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+{
+	struct sensor_device_attribute_2 *sensor_attr =
+						to_sensor_dev_attr_2(attr);
+
+	//sensor_attr->index : pwm_ch#
+	//sensor_attr->nr : attr#
+	switch(sensor_attr->nr) 
+	{
+		case 0: //enable, disable
+			return sprintf(sysfsbuf, "%d : %s\n", ast_get_tacho_en(ast_pwm_tacho,sensor_attr->index),ast_get_tacho_en(ast_pwm_tacho,sensor_attr->index) ? "Enable":"Disable");
+			break;
+		case 1: //tacho source PWMA~H - 0~7
+			return sprintf(sysfsbuf, "PWM%d (0~7)\n", ast_get_tacho_source(ast_pwm_tacho,sensor_attr->index));
+			break;
+		case 2: //rpm
+			return sprintf(sysfsbuf, "%d \n", ast_get_tacho_rpm(ast_pwm_tacho,sensor_attr->index));
+			break;			
+		case 3: //alarm
+			return sprintf(sysfsbuf, "%d \n", ast_get_tacho_alarm(ast_pwm_tacho,sensor_attr->index));
+			break;			
+		case 4: //alarm_en
+			return sprintf(sysfsbuf, "%d : %s\n", 
+				ast_get_tacho_alarm_en(ast_pwm_tacho,sensor_attr->index),
+				ast_get_tacho_alarm_en(ast_pwm_tacho,sensor_attr->index) ? "Enable":"Disable");
+			break;			
+		default:
+			return -EINVAL;
+			break;
+	}
+
+}
+
+static ssize_t 
+ast_store_tacho_speed(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
+{
+	u32 input_val;
+	struct sensor_device_attribute_2 *sensor_attr =
+						to_sensor_dev_attr_2(attr);
+
+	input_val = simple_strtoul(sysfsbuf, NULL, 10);
+
+
+	//sensor_attr->index : tacho_ch#
+	//sensor_attr->nr : attr#
+	switch(sensor_attr->nr) 
+	{
+		case 0: //enable, disable
+			ast_set_tacho_en(ast_pwm_tacho,sensor_attr->index,input_val);
+			break;
+		case 1: //tacho source PWMA~H - 0~7
+			ast_set_tacho_source(ast_pwm_tacho,sensor_attr->index,input_val);
+			break;
+		case 2: //rpm
+			return -EINVAL;
+			break;			
+		case 3: //alarm
+			return -EINVAL;
+			break;			
+		case 4: //alarm_en
+			ast_set_tacho_alarm_en(ast_pwm_tacho,sensor_attr->index,input_val);
+			break;			
+		default:
+			return -EINVAL;
+			break;
+	}
+	return count;
+}
+
+/*
+ * sysfs attributes
+ */
+/* CLK sysfs*/
+static SENSOR_DEVICE_ATTR_2(clk_en, S_IRUGO | S_IWUSR, ast_show_clk, ast_store_clk, 0, 0);
+static SENSOR_DEVICE_ATTR_2(clk_source, S_IRUGO | S_IWUSR, ast_show_clk, ast_store_clk, 1, 0); 
+
+
+static struct attribute *clk_attributes[] = { 
+	&sensor_dev_attr_clk_source.dev_attr.attr, 
+	&sensor_dev_attr_clk_en.dev_attr.attr, 
+	NULL 
+};
+
+static const struct attribute_group clk_attribute_groups = {
+	.attrs = clk_attributes,
+};
+
+/*PWM M/N/O Type sysfs*/
+/* 
+ * Macro defining SENSOR_DEVICE_ATTR for a pwm sysfs entries.
+ *  0 - show/store unit
+ *  1 - show/store division_l
+ *  2 - show/store division_h 
+ */
+
+#define sysfs_pwm_type(type,index) \
+static SENSOR_DEVICE_ATTR_2(pwm_type_##type##_unit, S_IRUGO | S_IWUSR, \
+	ast_show_pwm_type_clock, ast_store_pwm_type_clock, 0, index); \
+\
+static SENSOR_DEVICE_ATTR_2(pwm_type_##type##_division_l, S_IRUGO | S_IWUSR, \
+	ast_show_pwm_type_clock, ast_store_pwm_type_clock, 1, index); \
+\
+static SENSOR_DEVICE_ATTR_2(pwm_type_##type##_division_h, S_IRUGO | S_IWUSR, \
+	ast_show_pwm_type_clock, ast_store_pwm_type_clock, 2, index); \
+\
+static SENSOR_DEVICE_ATTR_2(pwm_type_##type##_clk, S_IRUGO, \
+	ast_show_pwm_type_clock, NULL, 3, index); \
+\
+static struct attribute *pwm_type_##type##_attributes[] = { \
+	&sensor_dev_attr_pwm_type_##type##_unit.dev_attr.attr, \
+	&sensor_dev_attr_pwm_type_##type##_division_l.dev_attr.attr, \
+	&sensor_dev_attr_pwm_type_##type##_division_h.dev_attr.attr, \
+	&sensor_dev_attr_pwm_type_##type##_clk.dev_attr.attr, \
+	NULL \
+};
+
+/*
+ * Create the needed functions for each pwm using the macro defined above
+ * (4 pwms are supported)
+ */
+sysfs_pwm_type(m,0);
+sysfs_pwm_type(n,1);
+#ifdef PWM_TYPE_O
+sysfs_pwm_type(o,2);
+#endif
+
+static const struct attribute_group pwm_type_attribute_groups[] = {
+	{ .attrs = pwm_type_m_attributes },
+	{ .attrs = pwm_type_n_attributes },
+#ifdef PWM_TYPE_O	
+	{ .attrs = pwm_type_o_attributes },
+#endif
+};
+
+/* PWM sysfs
+ * Macro defining SENSOR_DEVICE_ATTR for a pwm sysfs entries.
+ *  0 - show/store enable
+ *  1 - show/store type
+ *  2 - show/store rising
+ *  3 - show/store falling
+ */
+
+#define sysfs_pwm_speeds_num(index) \
+static SENSOR_DEVICE_ATTR_2(pwm##index##_en, S_IRUGO | S_IWUSR, \
+	ast_show_pwm_speed, ast_store_pwm_speed, 0, index); \
+\
+static SENSOR_DEVICE_ATTR_2(pwm##index##_type, S_IRUGO | S_IWUSR, \
+	ast_show_pwm_speed, ast_store_pwm_speed, 1, index); \
+\
+static SENSOR_DEVICE_ATTR_2(pwm##index##_rising, S_IRUGO | S_IWUSR, \
+	ast_show_pwm_speed, ast_store_pwm_speed, 2, index); \
+\
+static SENSOR_DEVICE_ATTR_2(pwm##index##_falling, S_IRUGO | S_IWUSR, \
+	ast_show_pwm_speed, ast_store_pwm_speed, 3, index); \
+\
+static struct attribute *pwm##index##_attributes[] = { \
+	&sensor_dev_attr_pwm##index##_en.dev_attr.attr, \
+	&sensor_dev_attr_pwm##index##_type.dev_attr.attr, \
+	&sensor_dev_attr_pwm##index##_rising.dev_attr.attr, \
+	&sensor_dev_attr_pwm##index##_falling.dev_attr.attr, \
+	NULL \
+};
+
+/*
+ * Create the needed functions for each pwm using the macro defined above
+ * (4 pwms are supported)
+ */
+sysfs_pwm_speeds_num(0);
+sysfs_pwm_speeds_num(1);
+sysfs_pwm_speeds_num(2);
+sysfs_pwm_speeds_num(3);
+sysfs_pwm_speeds_num(4);
+sysfs_pwm_speeds_num(5);
+sysfs_pwm_speeds_num(6);
+sysfs_pwm_speeds_num(7);
+
+static const struct attribute_group pwm_attribute_groups[] = {
+	{ .attrs = pwm0_attributes },
+	{ .attrs = pwm1_attributes },
+	{ .attrs = pwm2_attributes },
+	{ .attrs = pwm3_attributes },
+	{ .attrs = pwm4_attributes },
+	{ .attrs = pwm5_attributes },
+	{ .attrs = pwm6_attributes },
+	{ .attrs = pwm7_attributes },
+};
+
+/* Fan M/N/O Type sysfs 
+ * Macro defining SENSOR_DEVICE_ATTR for a pwm sysfs entries.
+ *  0 - show/store enable
+ *  1 - show/store mode
+ *  2 - show/store unit
+ *  3 - show/store division
+ *  4 - show/store limit
+ */
+
+#define sysfs_tacho_type(type,index) \
+static SENSOR_DEVICE_ATTR_2(tacho_type_##type##_en, S_IRUGO | S_IWUSR, \
+	ast_show_tacho_type, ast_store_tacho_type, 0, index); \
+\
+static SENSOR_DEVICE_ATTR_2(tacho_type_##type##_mode, S_IRUGO | S_IWUSR, \
+	ast_show_tacho_type, ast_store_tacho_type, 1, index); \
+\
+static SENSOR_DEVICE_ATTR_2(tacho_type_##type##_unit, S_IRUGO | S_IWUSR, \
+	ast_show_tacho_type, ast_store_tacho_type, 2, index); \
+\
+static SENSOR_DEVICE_ATTR_2(tacho_type_##type##_division, S_IRUGO | S_IWUSR, \
+	ast_show_tacho_type, ast_store_tacho_type, 3, index); \
+\
+static SENSOR_DEVICE_ATTR_2(tacho_type_##type##_limit, S_IRUGO | S_IWUSR, \
+	ast_show_tacho_type, ast_store_tacho_type, 4, index); \
+\
+static SENSOR_DEVICE_ATTR_2(tacho_type_##type##_measure_period, S_IRUGO | S_IWUSR, \
+	ast_show_tacho_type, ast_store_tacho_type, 5, index); \
+\
+static struct attribute *tacho_type_##type##_attributes[] = { \
+	&sensor_dev_attr_tacho_type_##type##_en.dev_attr.attr, \
+	&sensor_dev_attr_tacho_type_##type##_mode.dev_attr.attr, \
+	&sensor_dev_attr_tacho_type_##type##_unit.dev_attr.attr, \
+	&sensor_dev_attr_tacho_type_##type##_division.dev_attr.attr, \
+	&sensor_dev_attr_tacho_type_##type##_limit.dev_attr.attr, \
+	&sensor_dev_attr_tacho_type_##type##_measure_period.dev_attr.attr, \
+	NULL \
+};
+
+/*
+ * Create the needed functions for each pwm using the macro defined above
+ * (4 pwms are supported)
+ */
+sysfs_tacho_type(m,0);
+sysfs_tacho_type(n,1);
+#ifdef PWM_TYPE_O
+sysfs_tacho_type(o,2);
+#endif
+
+static const struct attribute_group tacho_type_attribute_groups[] = {
+	{ .attrs = tacho_type_m_attributes },
+	{ .attrs = tacho_type_n_attributes },
+#ifdef PWM_TYPE_O	
+	{ .attrs = tacho_type_o_attributes },
+#endif
+};
+
+/* FAN sysfs
+ * Macro defining SENSOR_DEVICE_ATTR for a tacho sysfs entries.
+ *  - show/store enable
+ *  - show/store source
+ *  - show/store rpm
+ *  - show/store alarm
+ *  - show/store alarm_en 
+ */
+#define sysfs_tacho_speeds_num(index) \
+static SENSOR_DEVICE_ATTR_2(tacho##index##_en, S_IRUGO | S_IWUSR, \
+	ast_show_tacho_speed, ast_store_tacho_speed, 0, index); \
+\
+static SENSOR_DEVICE_ATTR_2(tacho##index##_source, S_IRUGO | S_IWUSR, \
+	ast_show_tacho_speed, ast_store_tacho_speed, 1, index); \
+\
+static SENSOR_DEVICE_ATTR_2(tacho##index##_rpm, S_IRUGO, \
+	ast_show_tacho_speed, NULL, 2, index); \
+\
+static SENSOR_DEVICE_ATTR_2(tacho##index##_alarm, S_IRUGO, \
+	ast_show_tacho_speed, ast_store_tacho_speed, 3, index); \
+\
+static SENSOR_DEVICE_ATTR_2(tacho##index##_alarm_en, S_IRUGO | S_IWUSR, \
+	ast_show_tacho_speed, ast_store_tacho_speed, 4, index); \
+\
+static struct attribute *tacho##index##_attributes[] = { \
+	&sensor_dev_attr_tacho##index##_en.dev_attr.attr, \
+	&sensor_dev_attr_tacho##index##_source.dev_attr.attr, \
+	&sensor_dev_attr_tacho##index##_rpm.dev_attr.attr, \
+	&sensor_dev_attr_tacho##index##_alarm.dev_attr.attr, \
+	&sensor_dev_attr_tacho##index##_alarm_en.dev_attr.attr, \
+	NULL \
+};
+
+/*
+ * Create the needed functions for each tacho using the macro defined above
+ * (4 tachos are supported)
+ */
+sysfs_tacho_speeds_num(0);
+sysfs_tacho_speeds_num(1);
+sysfs_tacho_speeds_num(2);
+sysfs_tacho_speeds_num(3);
+sysfs_tacho_speeds_num(4);
+sysfs_tacho_speeds_num(5);
+sysfs_tacho_speeds_num(6);
+sysfs_tacho_speeds_num(7);
+sysfs_tacho_speeds_num(8);
+sysfs_tacho_speeds_num(9);
+sysfs_tacho_speeds_num(10);
+sysfs_tacho_speeds_num(11);
+sysfs_tacho_speeds_num(12);
+sysfs_tacho_speeds_num(13);
+sysfs_tacho_speeds_num(14);
+sysfs_tacho_speeds_num(15);
+
+static const struct attribute_group tacho_attribute_groups[] = {
+	{ .attrs = tacho0_attributes },
+	{ .attrs = tacho1_attributes },
+	{ .attrs = tacho2_attributes },
+	{ .attrs = tacho3_attributes },
+	{ .attrs = tacho4_attributes },
+	{ .attrs = tacho5_attributes },
+	{ .attrs = tacho6_attributes },
+	{ .attrs = tacho7_attributes },
+	{ .attrs = tacho8_attributes },
+	{ .attrs = tacho9_attributes },
+	{ .attrs = tacho10_attributes },
+	{ .attrs = tacho11_attributes },
+	{ .attrs = tacho12_attributes },
+	{ .attrs = tacho13_attributes },
+	{ .attrs = tacho14_attributes },
+	{ .attrs = tacho15_attributes },
+};
+
+static int 
+ast_pwm_tacho_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	int err;
+	int ret=0;
+	int i;
+
+	dev_dbg(&pdev->dev, "ast_pwm_fan_probe \n");
+
+	ast_pwm_tacho = kzalloc(sizeof(struct ast_pwm_tacho_data), GFP_KERNEL);
+	if (!ast_pwm_tacho) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ast_pwm_tacho->ast_pwm_data = pdev->dev.platform_data;	
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (NULL == res) {
+		dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
+		ret = -ENOENT;
+		goto out_mem;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res), res->name)) {
+		dev_err(&pdev->dev, "cannot reserved region\n");
+		ret = -ENXIO;
+		goto out_mem;
+	}
+
+	ast_pwm_tacho->reg_base = ioremap(res->start, resource_size(res));
+	if (!ast_pwm_tacho->reg_base) {
+		ret = -EIO;
+		goto out_region;
+	}
+
+	ast_pwm_tacho->irq = platform_get_irq(pdev, 0);
+	if (ast_pwm_tacho->irq < 0) {
+		dev_err(&pdev->dev, "no irq specified\n");
+		ret = -ENOENT;
+		goto out_region;
+	}
+
+	/* Register sysfs hooks */
+	err = sysfs_create_group(&pdev->dev.kobj, &clk_attribute_groups);
+	if (err)
+		goto out_region;
+
+	ast_pwm_tacho->hwmon_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(ast_pwm_tacho->hwmon_dev)) {
+		ret = PTR_ERR(ast_pwm_tacho->hwmon_dev);
+		goto out_sysfs0;
+	}
+
+	for(i=0; i< PWM_CH_NUM; i++) {
+		err = sysfs_create_group(&pdev->dev.kobj, &pwm_attribute_groups[i]);
+		if (err)
+			goto out_sysfs0;
+	}
+
+	for(i=0; i< PWM_TYPE_NUM; i++) {
+		err = sysfs_create_group(&pdev->dev.kobj, &pwm_type_attribute_groups[i]);
+		if (err)
+			goto out_sysfs1;
+	}
+	
+
+	for(i=0; i< TACHO_NUM; i++) {
+		err = sysfs_create_group(&pdev->dev.kobj, &tacho_attribute_groups[i]);
+		if (err)
+			goto out_sysfs2;
+	}
+
+	for(i=0; i< PWM_TYPE_NUM; i++) {
+		err = sysfs_create_group(&pdev->dev.kobj, &tacho_type_attribute_groups[i]);
+		if (err)
+			goto out_sysfs3;
+	}
+
+	ast_pwm_taco_init();
+	
+	printk(KERN_INFO "ast_pwm_tacho: driver successfully loaded.\n");
+
+	return 0;
+
+out_sysfs3:
+	for(i=0; i< TACHO_NUM; i++)
+		sysfs_remove_group(&pdev->dev.kobj, &tacho_attribute_groups[i]);
+
+out_sysfs2:
+	for(i=0; i< PWM_TYPE_NUM; i++)
+		sysfs_remove_group(&pdev->dev.kobj, &pwm_type_attribute_groups[i]);
+
+out_sysfs1:
+	for(i=0; i< PWM_CH_NUM; i++)
+		sysfs_remove_group(&pdev->dev.kobj, &pwm_attribute_groups[i]);
+out_sysfs0:
+	sysfs_remove_group(&pdev->dev.kobj, &clk_attribute_groups);
+
+//out_irq:
+//	free_irq(ast_pwm_tacho->irq, NULL);
+out_region:
+	release_mem_region(res->start, res->end - res->start + 1);
+out_mem:
+	kfree(ast_pwm_tacho);
+out:
+	printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
+	return ret;
+}
+
+static int 
+ast_pwm_tacho_remove(struct platform_device *pdev)
+{
+	int i=0;
+	struct ast_pwm_tacho_data *ast_pwm_tacho = platform_get_drvdata(pdev);
+	struct resource *res;
+	printk(KERN_INFO "ast_pwm_tacho: driver unloaded.\n");
+
+    hwmon_device_unregister(ast_pwm_tacho->hwmon_dev);
+
+	for(i=0; i<16; i++)
+		sysfs_remove_group(&pdev->dev.kobj, &tacho_attribute_groups[i]);
+
+	for(i=0; i<3; i++)
+		sysfs_remove_group(&pdev->dev.kobj, &pwm_type_attribute_groups[i]);
+
+	for(i=0; i<8; i++)
+		sysfs_remove_group(&pdev->dev.kobj, &pwm_attribute_groups[i]);
+
+	sysfs_remove_group(&pdev->dev.kobj, &clk_attribute_groups);
+
+	platform_set_drvdata(pdev, NULL);
+//	free_irq(ast_pwm_tacho->irq, ast_pwm_tacho);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	iounmap(ast_pwm_tacho->reg_base);
+	release_mem_region(res->start, res->end - res->start + 1);
+	kfree(ast_pwm_tacho);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int 
+ast_pwm_tacho_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	printk("ast_pwm_tacho_suspend : TODO \n");
+	return 0;
+}
+
+static int 
+ast_pwm_tacho_resume(struct platform_device *pdev)
+{
+	ast_pwm_taco_init();
+	return 0;
+}
+
+#else
+#define ast_pwm_tacho_suspend        NULL
+#define ast_pwm_tacho_resume         NULL
+#endif
+
+static struct platform_driver ast_pwm_tacho_driver = {
+	.probe			= ast_pwm_tacho_probe,
+	.remove 		= __devexit_p(ast_pwm_tacho_remove),
+    .suspend        = ast_pwm_tacho_suspend,
+    .resume         = ast_pwm_tacho_resume,
+    .driver         = {
+            .name   = "ast_pwm_tacho",
+            .owner  = THIS_MODULE,
+    },
+};
+
+static int __init 
+ast_pwm_tacho_init(void)
+{
+	return platform_driver_register(&ast_pwm_tacho_driver);
+}
+
+static void __exit 
+ast_pwm_tacho_exit(void)
+{
+	platform_driver_unregister(&ast_pwm_tacho_driver);
+}
+
+module_init(ast_pwm_tacho_init);
+module_exit(ast_pwm_tacho_exit);
+
+MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
+MODULE_DESCRIPTION("PWM TACHO driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 7f95905..2ed0928 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -454,6 +454,51 @@ config I2C_PXA_SLAVE
 	  is necessary for systems where the PXA may be a target on the
 	  I2C bus.
 
+config I2C_AST
+        tristate "ASPEED AST I2C adapter "
+#        depends on ARCH_ASPEED
+        help
+          If you have devices in the AST I2C bus, say yes to this option.
+          This driver can also be built as a module.  If so, the module
+          will be called i2c-ast.
+
+config I2C_AST1070
+        tristate "ASPEED AST1070 I2C adapter "
+        depends on ARCH_AST1070
+        help
+          If you have devices in the AST1070 I2C bus, say yes to this option.
+          This driver can also be built as a module.  If so, the module
+          will be called i2c-ast.
+
+config AST_I2C_SLAVE_MODE
+        bool "AST I2C Slave mode"
+	depends on I2C_AST
+
+if AST_I2C_SLAVE_MODE
+
+choice 
+	prompt "I2C slave config"
+        default AST_I2C_SLAVE_EEPROM
+
+config AST_I2C_SLAVE_EEPROM
+        bool "10 byte EEPROM Device"
+        help
+          Support I2C slave mode communications on the AST I2C bus.  This
+          is necessary for systems where the AST may be a target on the
+          I2C bus.
+	  
+config AST_I2C_SLAVE_RDWR
+        bool "I2C Slave RD/WR via ioctl"
+
+        help
+          Support I2C slave mode communications on the AST I2C bus.  This
+          is necessary for systems where the AST may be a target on the
+          I2C bus.
+
+endchoice
+
+endif
+
 config I2C_S3C2410
 	tristate "S3C2410 I2C Driver"
 	depends on ARCH_S3C2410
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 0c2c4b2..a3b523e 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_I2C_OMAP)		+= i2c-omap.o
 obj-$(CONFIG_I2C_PASEMI)	+= i2c-pasemi.o
 obj-$(CONFIG_I2C_PNX)		+= i2c-pnx.o
 obj-$(CONFIG_I2C_PXA)		+= i2c-pxa.o
+obj-$(CONFIG_I2C_AST)		+= i2c-ast.o
 obj-$(CONFIG_I2C_S3C2410)	+= i2c-s3c2410.o
 obj-$(CONFIG_I2C_SH7760)	+= i2c-sh7760.o
 obj-$(CONFIG_I2C_SH_MOBILE)	+= i2c-sh_mobile.o
diff --git a/drivers/i2c/busses/i2c-ast.c b/drivers/i2c/busses/i2c-ast.c
new file mode 100644
index 0000000..bccf5a3
--- /dev/null
+++ b/drivers/i2c/busses/i2c-ast.c
@@ -0,0 +1,1725 @@
+/*
+ *  i2c_adap_ast.c
+ *
+ *  I2C adapter for the ASPEED I2C bus access.
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology 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.
+ *
+ *  History:
+ *    2012.07.26: Initial version [Ryan Chen]
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <linux/dma-mapping.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#if defined(CONFIG_COLDFIRE)
+#include <asm/arch/regs-iic.h>
+#include <asm/arch/ast_i2c.h>
+#else
+#include <plat/regs-iic.h>
+#include <plat/ast_i2c.h>
+#endif
+
+//AST2400 buffer mode issue , force I2C slave write use byte mode , read use buffer mode 
+/* Use platform_data instead of module parameters */
+/* Fast Mode = 400 kHz, Standard = 100 kHz */
+//static int clock = 100; /* Default: 100 kHz */
+
+
+/***************************************************************************/
+struct ast_i2c_dev {
+	struct ast_i2c_driver_data *ast_i2c_data;
+	struct device		*dev;
+	void __iomem		*reg_base;			/* virtual */	
+	int 				irq;				//I2C IRQ number 
+	u32					bus_id;				//for i2c dev# IRQ number check 
+	u32					state;				//I2C xfer mode state matchine 
+	struct i2c_adapter	adap;
+	struct buf_page		*req_page;	
+//dma or buff mode needed
+	unsigned char		*dma_buf;
+	dma_addr_t			dma_addr;
+	
+//master	
+	int					xfer_last;			//cur xfer is last msgs for stop msgs
+	struct i2c_msg 		*master_msgs;		//cur xfer msgs
+	int					master_xfer_len;			//cur xfer len 
+	int					master_xfer_cnt;			//total xfer count
+	u32					master_xfer_mode;			//cur xfer mode ... 0 : no_op , master: 1 byte , 2 : buffer , 3: dma , slave : xxxx
+	struct completion	cmd_complete;
+	int					cmd_err;
+	u8 					blk_r_flag; 		//for smbus block read
+	void 				(*do_master_xfer)(struct ast_i2c_dev *i2c_dev);	
+//Slave structure	
+	u8					slave_operation;
+	u8					slave_event;
+	struct i2c_msg		*slave_msgs; 		//cur slave xfer msgs
+	int 				slave_xfer_len;			
+	int 				slave_xfer_cnt;		
+	u32					slave_xfer_mode;			//cur xfer mode ... 0 : no_op , master: 1 byte , 2 : buffer , 3: dma , slave : xxxx		
+	void				(*do_slave_xfer)(struct ast_i2c_dev *i2c_dev);
+};
+
+#ifdef CONFIG_AST_I2C_SLAVE_RDWR
+#define I2C_S_BUF_SIZE 		64
+#define I2C_S_RX_BUF_NUM 		4
+#define BUFF_FULL		0xff00
+#define BUFF_ONGOING	1	
+
+struct i2c_msg		slave_rx_msg[I2C_S_RX_BUF_NUM + 1];
+struct i2c_msg		slave_tx_msg;	
+#endif
+
+
+static inline void
+ast_i2c_write(struct ast_i2c_dev *i2c_dev, u32 val, u32 reg)
+{
+//	dev_dbg(i2c_dev->dev, "ast_i2c_write : val: %x , reg : %x \n",val,reg);	
+	writel(val, i2c_dev->reg_base+ reg);
+}
+
+static inline u32
+ast_i2c_read(struct ast_i2c_dev *i2c_dev, u32 reg)
+{
+#if 0
+	u32 val = readl(i2c_dev->reg_base + reg);
+	printk("R : reg %x , val: %x \n",reg, val);
+	return val;
+#else	
+	return readl(i2c_dev->reg_base + reg);
+#endif
+}
+
+static u32 select_i2c_clock(struct ast_i2c_dev *i2c_dev)
+{
+
+	unsigned int clk, inc = 0, div, divider_ratio;
+	u32 SCL_Low, SCL_High, data;
+
+	clk = i2c_dev->ast_i2c_data->get_i2c_clock();
+//	printk("pclk = %d \n",clk);
+	divider_ratio = clk / i2c_dev->ast_i2c_data->bus_clk;
+	for (div = 0; divider_ratio >= 16; div++)
+	{
+		inc |= (divider_ratio & 1);
+		divider_ratio >>= 1;
+	}
+	divider_ratio += inc;
+	SCL_Low = (divider_ratio >> 1) - 1;
+	SCL_High = divider_ratio - SCL_Low - 2;
+	data = 0x77700300 | (SCL_High << 16) | (SCL_Low << 12) | div;
+//	printk("I2CD04 for %d = %08X\n", target_speed, data);
+	return data;
+}
+
+#ifdef CONFIG_AST_I2C_SLAVE_MODE
+/* AST I2C Slave mode  */
+static void ast_slave_issue_alert(struct ast_i2c_dev *i2c_dev, u8 enable)
+{
+	//only support dev0~3
+	if(i2c_dev->bus_id > 3)
+		return;
+	else {
+		if(enable)
+			ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_CMD_REG) | AST_I2CD_S_ALT_EN, I2C_CMD_REG);
+		else
+			ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_CMD_REG) & ~AST_I2CD_S_ALT_EN, I2C_CMD_REG);
+	}
+}
+
+static void ast_slave_mode_enable(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msgs)
+{
+	if(msgs->buf[0] == 1) {
+		ast_i2c_write(i2c_dev, msgs->addr, I2C_DEV_ADDR_REG);	
+		ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_FUN_CTRL_REG) | AST_I2CD_SLAVE_EN, I2C_FUN_CTRL_REG);
+	} else
+		ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_FUN_CTRL_REG) & ~AST_I2CD_SLAVE_EN, I2C_FUN_CTRL_REG);
+}
+
+#endif
+
+static void ast_i2c_dev_init(struct ast_i2c_dev *i2c_dev)
+{
+	//I2CG Reset 
+	ast_i2c_write(i2c_dev, 0, I2C_FUN_CTRL_REG);
+
+#ifdef CONFIG_AST_I2C_SLAVE_EEPROM	
+	i2c_dev->ast_i2c_data->slave_init(&(i2c_dev->slave_msgs));
+	ast_slave_mode_enable(i2c_dev, i2c_dev->slave_msgs);
+#endif
+
+	//Enable Master Mode
+	ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev, I2C_FUN_CTRL_REG) | AST_I2CD_MASTER_EN, I2C_FUN_CTRL_REG);
+
+
+	/* Set AC Timing */
+#if defined(CONFIG_ARCH_AST2400)
+	if(i2c_dev->ast_i2c_data->bus_clk/1000 > 400) {
+		printk("high speed mode enable clk [%dkhz]\n",i2c_dev->ast_i2c_data->bus_clk/1000);		
+		ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev, I2C_FUN_CTRL_REG) |
+							AST_I2CD_M_HIGH_SPEED_EN |
+							AST_I2CD_M_SDA_DRIVE_1T_EN |
+							AST_I2CD_SDA_DRIVE_1T_EN 
+							, I2C_FUN_CTRL_REG);
+		
+		/* Set AC Timing */
+		ast_i2c_write(i2c_dev, 0x3, I2C_AC_TIMING_REG2);
+		ast_i2c_write(i2c_dev, select_i2c_clock(i2c_dev), I2C_AC_TIMING_REG1);		
+	}else {
+		/* target apeed is xxKhz*/	
+		ast_i2c_write(i2c_dev, select_i2c_clock(i2c_dev), I2C_AC_TIMING_REG1);
+		ast_i2c_write(i2c_dev, AST_NO_TIMEOUT_CTRL, I2C_AC_TIMING_REG2);	
+	}
+#else
+	/* target apeed is xxKhz*/
+	ast_i2c_write(i2c_dev, select_i2c_clock(i2c_dev), I2C_AC_TIMING_REG1);
+	ast_i2c_write(i2c_dev, AST_NO_TIMEOUT_CTRL, I2C_AC_TIMING_REG2);
+#endif
+//	ast_i2c_write(i2c_dev, 0x77743335, I2C_AC_TIMING_REG1);
+/////
+
+
+	//Clear Interrupt
+	ast_i2c_write(i2c_dev, 0xfffffff, I2C_INTR_STS_REG);
+
+	//TODO
+//	ast_i2c_write(i2c_dev, 0xAF, I2C_INTR_CTRL_REG);
+	//Enable Interrupt, STOP Interrupt has bug in AST2000 
+	
+	/* Set interrupt generation of I2C controller */
+	ast_i2c_write(i2c_dev,
+				AST_I2CD_SDA_DL_TO_INTR_EN | 	
+				AST_I2CD_BUS_RECOVER_INTR_EN | 	
+				AST_I2CD_SMBUS_ALT_INTR_EN |
+//				AST_I2CD_SLAVE_MATCH_INTR_EN |
+				AST_I2CD_SCL_TO_INTR_EN |
+				AST_I2CD_ABNORMAL_INTR_EN |
+				AST_I2CD_NORMAL_STOP_INTR_EN |
+				AST_I2CD_ARBIT_LOSS_INTR_EN |
+				AST_I2CD_RX_DOWN_INTR_EN |
+				AST_I2CD_TX_NAK_INTR_EN |
+				AST_I2CD_TX_ACK_INTR_EN,
+				I2C_INTR_CTRL_REG);
+
+}
+
+#ifdef CONFIG_AST_I2C_SLAVE_RDWR
+//for memory buffer initial
+static void ast_i2c_slave_buff_init(struct ast_i2c_dev *i2c_dev)
+{
+	int i;
+	//Tx buf  1 
+	slave_tx_msg.len = I2C_S_BUF_SIZE;
+	slave_tx_msg.buf = kzalloc(I2C_S_BUF_SIZE, GFP_KERNEL);
+	//Rx buf 4
+	for(i=0; i<I2C_S_RX_BUF_NUM+1; i++) {
+		slave_rx_msg[i].addr = ~BUFF_ONGOING;
+		slave_rx_msg[i].flags = 0;	//mean empty buffer 
+		slave_rx_msg[i].len = I2C_S_BUF_SIZE;
+		slave_rx_msg[i].buf = kzalloc(I2C_S_BUF_SIZE, GFP_KERNEL);
+	}	
+}
+
+static void ast_i2c_slave_rdwr_xfer(struct ast_i2c_dev *i2c_dev)
+{
+	int i;
+	spinlock_t	lock;
+	spin_lock(&lock);	
+	
+	switch(i2c_dev->slave_event) {
+		case I2C_SLAVE_EVENT_START_WRITE:
+			for(i=0; i<I2C_S_RX_BUF_NUM; i++) {
+				if((slave_rx_msg[i].flags == 0) && (slave_rx_msg[i].addr != BUFF_ONGOING)) {
+					slave_rx_msg[i].addr = BUFF_ONGOING;
+					break;
+				}
+			}
+			if(i == I2C_S_RX_BUF_NUM) {
+				printk("RX buffer full ........use tmp msgs buff \n");
+				//TODO...
+			}
+			printk("I2C_SLAVE_EVENT_START_WRITE ... %d \n", i);
+
+			i2c_dev->slave_msgs = &slave_rx_msg[i];
+			break;
+		case I2C_SLAVE_EVENT_START_READ:
+			printk("I2C_SLAVE_EVENT_START_READ ERROR .. not imple \n");
+			i2c_dev->slave_msgs = &slave_tx_msg;
+			break;
+		case I2C_SLAVE_EVENT_WRITE:
+			printk("I2C_SLAVE_EVENT_WRITE next write ERROR ...\n");			
+			i2c_dev->slave_msgs = &slave_tx_msg;
+			break;
+		case I2C_SLAVE_EVENT_READ:
+			printk("I2C_SLAVE_EVENT_READ ERROR ... \n");			
+			i2c_dev->slave_msgs = &slave_tx_msg;
+			break;
+		case I2C_SLAVE_EVENT_NACK:
+			printk("I2C_SLAVE_EVENT_NACK ERROR ... \n");			
+			i2c_dev->slave_msgs = &slave_tx_msg;
+			break;
+		case I2C_SLAVE_EVENT_STOP:
+			printk("I2C_SLAVE_EVENT_STOP \n");			
+			for(i=0; i<I2C_S_RX_BUF_NUM; i++) {
+				if(slave_rx_msg[i].addr == BUFF_ONGOING) {
+					slave_rx_msg[i].flags = BUFF_FULL;
+					slave_rx_msg[i].addr = 0;
+					break;
+				}
+			}
+			
+			i2c_dev->slave_msgs = &slave_tx_msg;
+			break;
+	}
+	spin_unlock(&lock);	
+
+}
+
+static int ast_i2c_slave_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
+{
+	struct ast_i2c_dev *i2c_dev = adap->algo_data;
+	int ret=0, i;
+
+	switch(msgs->flags) {
+		case 0:
+//			printk("slave read \n");
+			//cur_msg = get_free_msg;
+			for(i=0; i<I2C_S_RX_BUF_NUM; i++) {
+				if((slave_rx_msg[i].addr == 0) && (slave_rx_msg[i].flags == BUFF_FULL)) {
+					memcpy(msgs->buf, slave_rx_msg[i].buf, slave_rx_msg[i].len);
+					msgs->len = slave_rx_msg[i].len;
+					slave_rx_msg[i].flags = 0;
+					slave_rx_msg[i].len = 0;
+					break;
+				}
+			}
+			
+			if(i == I2C_S_RX_BUF_NUM) {
+				printk("No buffer ........ \n");
+				msgs->len = 0;
+				ret = -1;
+			}
+			break;
+		case I2C_M_RD:	//slave write
+//			printk("slave write \n");
+			memcpy(msgs->buf, slave_tx_msg.buf, I2C_S_BUF_SIZE);
+			break;		
+		case I2C_S_EN:
+			if((msgs->addr < 0x1) || (msgs->addr > 0xff)) {
+				ret = -1;
+				printk("addrsss not correct !! \n");
+				return ret;
+			}
+			if(msgs->len != 1) printk("ERROR \n");
+			ast_slave_mode_enable(i2c_dev, msgs);
+			break;
+		case I2C_S_ALT:
+//			printk("slave issue alt\n");
+			if(msgs->len != 1) printk("ERROR \n");
+			if(msgs->buf[0]==1)
+				ast_slave_issue_alert(i2c_dev, 1);
+			else
+				ast_slave_issue_alert(i2c_dev, 0);
+			break;
+
+		default:
+			printk("slave xfer error \n");
+			break;
+		
+	}
+	return ret;
+}
+
+
+#endif
+
+static u8 
+ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
+{
+	u32 sts;
+	int r;		
+	u32 i = 0;
+	
+	//Check 0x14's SDA and SCL status
+	sts = ast_i2c_read(i2c_dev,I2C_CMD_REG);
+	
+	if ((sts & AST_I2CD_SDA_LINE_STS) && (sts & AST_I2CD_SCL_LINE_STS)) {
+		//Means bus is idle.
+		dev_dbg(i2c_dev->dev, "I2C bus (%d) is idle. I2C slave doesn't exist?!\n", i2c_dev->bus_id);
+		return -1;
+	}
+
+	dev_dbg(i2c_dev->dev, "ERROR!! I2C(%d) bus hanged, try to recovery it!\n", i2c_dev->bus_id);
+	
+	
+	if ((sts & AST_I2CD_SDA_LINE_STS) && !(sts & AST_I2CD_SCL_LINE_STS)) {
+		//if SDA == 1 and SCL == 0, it means the master is locking the bus.
+		//Send a stop command to unlock the bus.		
+		dev_dbg(i2c_dev->dev, "I2C's master is locking the bus, try to stop it.\n");
+//
+		init_completion(&i2c_dev->cmd_complete);
+
+		ast_i2c_write(i2c_dev, AST_I2CD_M_STOP_CMD, I2C_CMD_REG);
+
+		r = wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
+													   i2c_dev->adap.timeout*HZ);
+
+		if(i2c_dev->cmd_err) {
+			dev_dbg(i2c_dev->dev, "recovery error \n");
+			return -1;
+		}
+			
+		if (r == 0) {
+			 dev_dbg(i2c_dev->dev, "recovery timed out\n");
+			 return -1;
+		} else {
+			dev_dbg(i2c_dev->dev, "Recovery successfully\n");		
+			return 0;
+		}
+
+
+	} else if (!(sts & AST_I2CD_SDA_LINE_STS)) {
+		//else if SDA == 0, the device is dead. We need to reset the bus
+		//And do the recovery command.
+		dev_dbg(i2c_dev->dev, "I2C's slave is dead, try to recover it\n");
+		//Let's retry 10 times
+		for (i = 0; i < 10; i++) {
+			ast_i2c_dev_init(i2c_dev);
+			//Do the recovery command BIT11
+			init_completion(&i2c_dev->cmd_complete);			
+			ast_i2c_write(i2c_dev, AST_I2CD_BUS_RECOVER_CMD_EN, I2C_CMD_REG);
+			
+			r = wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
+														   i2c_dev->adap.timeout*HZ);			
+			if (i2c_dev->cmd_err != 0) {
+				dev_dbg(i2c_dev->dev, "ERROR!! Failed to do recovery command(0x%08x)\n", i2c_dev->cmd_err);
+				return -1;
+			}
+			//Check 0x14's SDA and SCL status
+			sts = ast_i2c_read(i2c_dev,I2C_CMD_REG);
+			if (sts & AST_I2CD_SDA_LINE_STS) //Recover OK
+				break;
+		}
+		if (i == 10) {
+			dev_dbg(i2c_dev->dev, "ERROR!! recover failed\n");
+			return -1;
+		}
+	} else {
+		dev_dbg(i2c_dev->dev, "Don't know how to handle this case?!\n");
+		return -1;
+	}
+	dev_dbg(i2c_dev->dev, "Recovery successfully\n");
+	return 0;
+}
+
+static void ast_master_alert_recv(struct ast_i2c_dev *i2c_dev)	
+{
+	printk("ast_master_alert_recv bus id %d, Disable Alt, Please Imple \n",i2c_dev->bus_id);
+}
+
+static int ast_i2c_wait_bus_not_busy(struct ast_i2c_dev *i2c_dev)
+{
+	int timeout = 32; //TODO number
+//	printk("ast_i2c_wait_bus_not_busy \n");
+	while (ast_i2c_read(i2c_dev,I2C_CMD_REG) & AST_I2CD_BUS_BUSY_STS) {
+		ast_i2c_bus_error_recover(i2c_dev);
+		if(timeout<=0)
+			break;
+		timeout--;
+		msleep(2);
+	}
+
+	return timeout <= 0 ? EAGAIN : 0;
+}
+
+static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)	
+{
+	u32 cmd = 0;
+	int i;
+
+	i2c_dev->master_xfer_mode = DMA_XFER;
+	i2c_dev->slave_xfer_mode = DMA_XFER;
+
+	if(i2c_dev->slave_operation == 1) { 
+		if(i2c_dev->slave_msgs->flags & I2C_M_RD) {
+			//DMA tx mode
+			if(i2c_dev->slave_msgs->len > AST_I2C_DMA_SIZE)
+				i2c_dev->slave_xfer_len = AST_I2C_DMA_SIZE;
+			else 
+				i2c_dev->slave_xfer_len = i2c_dev->slave_msgs->len;
+			
+			dev_dbg(i2c_dev->dev, "(<--) slave tx DMA \n");
+			for(i=0; i<i2c_dev->slave_xfer_len; i++)
+				i2c_dev->dma_buf[i] = i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt + i];
+			
+			ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+			ast_i2c_write(i2c_dev, (i2c_dev->slave_xfer_len-1), I2C_DMA_LEN_REG);
+			ast_i2c_write(i2c_dev, AST_I2CD_TX_DMA_ENABLE | AST_I2CD_S_TX_CMD,I2C_CMD_REG);	
+		} else {
+			//DMA prepare rx
+			dev_dbg(i2c_dev->dev, "(-->) slave rx DMA \n");
+			ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+			ast_i2c_write(i2c_dev, (AST_I2C_DMA_SIZE-1), I2C_DMA_LEN_REG);
+			ast_i2c_write(i2c_dev, AST_I2CD_RX_DMA_ENABLE, I2C_CMD_REG);		
+		}
+	} else {
+		dev_dbg(i2c_dev->dev,"M cnt %d, xf len %d \n",i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+		if(i2c_dev->master_xfer_cnt == -1) {
+			//send start 
+			dev_dbg(i2c_dev->dev, " %sing %d byte%s %s 0x%02x\n",
+							i2c_dev->master_msgs->flags & I2C_M_RD ? "read" : "write",
+							i2c_dev->master_msgs->len, i2c_dev->master_msgs->len > 1 ? "s" : "",
+							i2c_dev->master_msgs->flags & I2C_M_RD ? "from" : "to", i2c_dev->master_msgs->addr);
+
+			if(i2c_dev->master_msgs->flags & I2C_M_RD) {
+				//workaround .. HW can;t send start read addr with buff mode 
+				cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD;
+				ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1) |0x1, I2C_BYTE_BUF_REG);
+
+//				tx_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
+				i2c_dev->master_xfer_len = 1;
+				ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+									AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);	
+			} else {
+				//tx
+				cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD | AST_I2CD_TX_DMA_ENABLE;		
+
+				i2c_dev->dma_buf[0] = (i2c_dev->master_msgs->addr <<1);	//+1
+				//next data write
+				if((i2c_dev->master_msgs->len + 1) > AST_I2C_DMA_SIZE)
+					i2c_dev->master_xfer_len = AST_I2C_DMA_SIZE;
+				else
+					i2c_dev->master_xfer_len = i2c_dev->master_msgs->len + 1;
+				
+				for(i = 1; i < i2c_dev->master_xfer_len; i++)
+					i2c_dev->dma_buf[i] = i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt+i];
+				
+				if (i2c_dev->xfer_last == 1) {
+					dev_dbg(i2c_dev->dev, "last stop \n");
+					cmd |= AST_I2CD_M_STOP_CMD;
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+										~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);				
+					
+				} else {
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+										AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);			
+				}
+				ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+				ast_i2c_write(i2c_dev, (i2c_dev->master_xfer_len-1), I2C_DMA_LEN_REG);
+				
+			}
+			ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);			
+			dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+
+		} else if (i2c_dev->master_xfer_cnt < i2c_dev->master_msgs->len){
+			//Next send 
+			if(i2c_dev->master_msgs->flags & I2C_M_RD) {
+				//Rx data
+				cmd = AST_I2CD_M_RX_CMD | AST_I2CD_RX_DMA_ENABLE;
+															
+				if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > AST_I2C_DMA_SIZE) {
+					i2c_dev->master_xfer_len = AST_I2C_DMA_SIZE;
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+										AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+					
+				} else {
+					i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
+					if((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+						dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN \n");
+						ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+											AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);						
+					} else {
+#ifdef CONFIG_AST1010
+						//Workaround for ast1010 can't send NACK
+						if((i2c_dev->master_xfer_len == 1) && (i2c_dev->xfer_last == 1)) {
+							//change to byte mode
+							cmd |= AST_I2CD_M_STOP_CMD | AST_I2CD_M_S_RX_CMD_LAST;
+							cmd &= ~AST_I2CD_RX_DMA_ENABLE;
+							i2c_dev->master_xfer_mode = BYTE_XFER;
+							ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+												~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+							
+						} else if (i2c_dev->master_xfer_len > 1) {
+							i2c_dev->master_xfer_len -=1;
+							ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+											AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+						} else {
+							printk(" Fix Me !! \n");
+						}
+#else
+						if(i2c_dev->xfer_last == 1) {
+							dev_dbg(i2c_dev->dev, "last stop \n");							
+							cmd |= AST_I2CD_M_STOP_CMD; 
+							ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+											~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+						} else {
+							ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+											AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+						}
+						//TODO check....
+						cmd |= AST_I2CD_M_S_RX_CMD_LAST;
+#endif						
+					}
+					
+				}
+				ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+				ast_i2c_write(i2c_dev, i2c_dev->master_xfer_len-1, I2C_DMA_LEN_REG);
+				ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
+				dev_dbg(i2c_dev->dev, "rxfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+			} else {
+				//Tx data
+				//next data write
+				cmd = AST_I2CD_M_TX_CMD | AST_I2CD_TX_DMA_ENABLE;
+				if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > AST_I2C_DMA_SIZE) {
+					i2c_dev->master_xfer_len = AST_I2C_DMA_SIZE;
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+										AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);			
+				
+				} else {
+					i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
+					if(i2c_dev->xfer_last == 1) {
+						dev_dbg(i2c_dev->dev, "last stop \n");
+						cmd |= AST_I2CD_M_STOP_CMD;
+						ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+											~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);				
+						
+					} else {
+						ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+											AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);			
+					}
+				}
+
+				for(i = 0; i < i2c_dev->master_xfer_len; i++) 
+					i2c_dev->dma_buf[i] = i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i];
+
+				ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+				ast_i2c_write(i2c_dev, (i2c_dev->master_xfer_len-1), I2C_DMA_LEN_REG);
+				ast_i2c_write(i2c_dev, cmd , I2C_CMD_REG);
+				dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+
+			}		
+		}else {
+			//should send next msg 
+			 if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
+					 printk("complete rx ... ERROR \n");
+			
+			 dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
+			 i2c_dev->cmd_err = 0;
+			 complete(&i2c_dev->cmd_complete);		
+		}
+	
+	}
+
+	
+}
+
+static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)	
+{
+	u32 cmd = 0;
+	int i;
+	u32 *tx_buf;
+
+	i2c_dev->master_xfer_mode = BUFF_XFER;
+	i2c_dev->slave_xfer_mode = BUFF_XFER; 	
+	
+#if defined(CONFIG_ARCH_AST2400)
+	ast_i2c_write(i2c_dev,
+					(ast_i2c_read(i2c_dev, I2C_FUN_CTRL_REG) &
+					~AST_I2CD_BUFF_SEL_MASK) |
+					AST_I2CD_BUFF_SEL(i2c_dev->req_page->page_no),
+					I2C_FUN_CTRL_REG);
+#endif
+
+	tx_buf = (u32 *) i2c_dev->req_page->page_addr;
+
+
+	if(i2c_dev->slave_operation == 1) { 
+		if(i2c_dev->slave_msgs->flags & I2C_M_RD) {
+			dev_dbg(i2c_dev->dev, "(<--) slave tx buf \n");
+	
+			if(i2c_dev->slave_msgs->len > i2c_dev->req_page->page_size)
+				i2c_dev->slave_xfer_len = i2c_dev->req_page->page_size;
+			else
+				i2c_dev->slave_xfer_len = i2c_dev->slave_msgs->len;
+			
+			for(i = 0; i< i2c_dev->slave_xfer_len; i++) {
+				if(i%4 == 0)
+					tx_buf[i/4] = 0;
+				tx_buf[i/4] |= (i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt + i] << ((i%4)*8)) ;
+				dev_dbg(i2c_dev->dev, "[%x] ",tx_buf[i/4]);
+			}
+			dev_dbg(i2c_dev->dev, "\n");
+		
+			ast_i2c_write(i2c_dev, AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->slave_xfer_len-1)) | 
+						AST_I2CD_BUF_BASE_ADDR_SET((i2c_dev->req_page->page_addr_point)), 
+						I2C_BUF_CTRL_REG);
+		
+			ast_i2c_write(i2c_dev, AST_I2CD_TX_BUFF_ENABLE | AST_I2CD_S_TX_CMD, I2C_CMD_REG);
+		} else {
+			//prepare for new rx
+			dev_dbg(i2c_dev->dev, "(-->) slave prepare rx buf \n");
+			ast_i2c_write(i2c_dev, 
+						AST_I2CD_RX_BUF_END_ADDR_SET((i2c_dev->req_page->page_size-1)) |
+						AST_I2CD_BUF_BASE_ADDR_SET((i2c_dev->req_page->page_addr_point)),
+						I2C_BUF_CTRL_REG);
+
+			ast_i2c_write(i2c_dev, AST_I2CD_RX_BUFF_ENABLE, I2C_CMD_REG);			
+			
+		}
+	} else {
+		dev_dbg(i2c_dev->dev,"M cnt %d, xf len %d \n",i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+		if(i2c_dev->master_xfer_cnt == -1) {
+			//send start 
+			dev_dbg(i2c_dev->dev, " %sing %d byte%s %s 0x%02x\n",
+							i2c_dev->master_msgs->flags & I2C_M_RD ? "read" : "write",
+							i2c_dev->master_msgs->len, i2c_dev->master_msgs->len > 1 ? "s" : "",
+							i2c_dev->master_msgs->flags & I2C_M_RD ? "from" : "to", i2c_dev->master_msgs->addr);
+
+			if(i2c_dev->master_msgs->flags & I2C_M_RD) {
+//workaround .. HW can;t send start read addr with buff mode 
+				cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD;
+				ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1) |0x1, I2C_BYTE_BUF_REG);
+
+//				tx_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
+				i2c_dev->master_xfer_len = 1;
+				ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+									AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);			
+			} else {
+				cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD | AST_I2CD_TX_BUFF_ENABLE;			
+				tx_buf[0] = (i2c_dev->master_msgs->addr <<1);	//+1
+				//next data write
+				if((i2c_dev->master_msgs->len + 1) > i2c_dev->req_page->page_size)
+					i2c_dev->master_xfer_len = i2c_dev->req_page->page_size;
+				else
+					i2c_dev->master_xfer_len = i2c_dev->master_msgs->len + 1;
+				
+				for(i = 1; i < i2c_dev->master_xfer_len; i++) {
+					if(i%4 == 0)
+						tx_buf[i/4] = 0;
+					tx_buf[i/4] |= (i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i] << ((i%4)*8)) ;
+				}
+				
+				if (i2c_dev->xfer_last == 1) {
+					dev_dbg(i2c_dev->dev, "last stop \n");
+					cmd |= AST_I2CD_M_STOP_CMD;
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+										~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);				
+					
+				} else {
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+										AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);			
+				}
+				ast_i2c_write(i2c_dev, 
+							AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->master_xfer_len - 1)) |
+							AST_I2CD_BUF_BASE_ADDR_SET(i2c_dev->req_page->page_addr_point),
+							I2C_BUF_CTRL_REG);
+			}
+			ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);			
+			dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+
+		} else if (i2c_dev->master_xfer_cnt < i2c_dev->master_msgs->len){
+			//Next send 
+			if(i2c_dev->master_msgs->flags & I2C_M_RD) {
+				//Rx data
+				cmd = AST_I2CD_M_RX_CMD | AST_I2CD_RX_BUFF_ENABLE;
+															
+				if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > i2c_dev->req_page->page_size) {
+					i2c_dev->master_xfer_len = i2c_dev->req_page->page_size;
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+										AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+				} else {
+					i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
+					if((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+						dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN \n");
+						ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+											AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);						
+					} else {
+						if(i2c_dev->xfer_last == 1) {
+							dev_dbg(i2c_dev->dev, "last stop \n");							
+							cmd |= AST_I2CD_M_STOP_CMD; 
+							ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+											~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+						} else {
+							ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+											AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+						}
+						cmd |= AST_I2CD_M_S_RX_CMD_LAST;
+					}
+				}
+				ast_i2c_write(i2c_dev,
+									AST_I2CD_RX_BUF_END_ADDR_SET((i2c_dev->master_xfer_len-1))|
+									AST_I2CD_BUF_BASE_ADDR_SET((i2c_dev->req_page->page_addr_point)),
+									I2C_BUF_CTRL_REG);
+				ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
+				dev_dbg(i2c_dev->dev, "rxfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+			} else {
+				//Tx data
+				//next data write
+				cmd = AST_I2CD_M_TX_CMD | AST_I2CD_TX_BUFF_ENABLE;
+				if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > i2c_dev->req_page->page_size) {
+					i2c_dev->master_xfer_len = i2c_dev->req_page->page_size;
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+										AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);			
+				
+				} else {
+					i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
+					if(i2c_dev->xfer_last == 1) {
+						dev_dbg(i2c_dev->dev, "last stop \n");
+						cmd |= AST_I2CD_M_STOP_CMD;
+						ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+											~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);				
+						
+					} else {
+						ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+											AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);			
+					}
+				}
+				
+				for(i = 0; i < i2c_dev->master_xfer_len; i++) {
+					if(i%4 == 0)
+						tx_buf[i/4] = 0;
+					tx_buf[i/4] |= (i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i] << ((i%4)*8)) ;
+				}
+//				printk("count %x \n",ast_i2c_read(i2c_dev,I2C_CMD_REG));				
+				ast_i2c_write(i2c_dev, 
+							AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->master_xfer_len - 1)) |
+							AST_I2CD_BUF_BASE_ADDR_SET(i2c_dev->req_page->page_addr_point),
+							I2C_BUF_CTRL_REG);
+		
+				ast_i2c_write(i2c_dev, cmd , I2C_CMD_REG);
+				dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+			}
+		} else {
+			//should send next msg 
+			if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
+				printk("complete rx ... ERROR \n");
+			
+			dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
+			i2c_dev->cmd_err = 0;
+			complete(&i2c_dev->cmd_complete);										
+		}
+
+	}
+}
+static void ast_i2c_do_byte_xfer(struct ast_i2c_dev *i2c_dev)
+{
+	u8 *xfer_buf;
+	u32 cmd = 0;
+
+	i2c_dev->master_xfer_mode = BYTE_XFER;
+	i2c_dev->master_xfer_len = 1;
+
+	i2c_dev->slave_xfer_mode = BYTE_XFER;	
+	i2c_dev->slave_xfer_len = 1;
+	
+	if(i2c_dev->slave_operation == 1) { 
+		dev_dbg(i2c_dev->dev,"S cnt %d, xf len %d \n",i2c_dev->slave_xfer_cnt, i2c_dev->slave_msgs->len);
+		if(i2c_dev->slave_msgs->flags & I2C_M_RD) {
+			//READ <-- TX
+			dev_dbg(i2c_dev->dev, "(<--) slave(tx) buf %d [%x]\n", i2c_dev->slave_xfer_cnt, i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt]);
+			ast_i2c_write(i2c_dev, i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt], I2C_BYTE_BUF_REG);
+			ast_i2c_write(i2c_dev, AST_I2CD_S_TX_CMD, I2C_CMD_REG); 
+		} else {
+			// Write -->Rx
+			//no need to handle in byte mode
+			dev_dbg(i2c_dev->dev, "(-->) slave(rx) BYTE do nothing\n");
+
+		}
+	} else {
+		dev_dbg(i2c_dev->dev,"M cnt %d, xf len %d \n",i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+		if(i2c_dev->master_xfer_cnt == -1) {
+			//first start 
+			dev_dbg(i2c_dev->dev, " %sing %d byte%s %s 0x%02x\n",
+							i2c_dev->master_msgs->flags & I2C_M_RD ? "read" : "write",
+							i2c_dev->master_msgs->len, i2c_dev->master_msgs->len > 1 ? "s" : "",
+							i2c_dev->master_msgs->flags & I2C_M_RD ? "from" : "to", i2c_dev->master_msgs->addr);
+			
+		
+			if(i2c_dev->master_msgs->flags & I2C_M_RD) 
+				ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1) |0x1, I2C_BYTE_BUF_REG);
+			else
+				ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1), I2C_BYTE_BUF_REG);
+
+			ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+								AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);			
+			
+			ast_i2c_write(i2c_dev, AST_I2CD_M_TX_CMD | AST_I2CD_M_START_CMD, I2C_CMD_REG);
+
+
+		} else if (i2c_dev->master_xfer_cnt < i2c_dev->master_msgs->len){
+			xfer_buf = i2c_dev->master_msgs->buf;
+			if(i2c_dev->master_msgs->flags & I2C_M_RD) {
+				//Rx data
+				cmd = AST_I2CD_M_RX_CMD;
+				if((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->master_xfer_cnt == 0)) {
+					dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN \n");
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+										AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);			
+
+				} else if((i2c_dev->xfer_last == 1) && (i2c_dev->master_xfer_cnt + 1 == i2c_dev->master_msgs->len)) {
+					cmd |= AST_I2CD_M_S_RX_CMD_LAST | AST_I2CD_M_STOP_CMD;
+	//				disable rx_dwn isr
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+										~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+				} else {
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+										AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);			
+				}
+
+				dev_dbg(i2c_dev->dev, "(<--) rx byte, cmd = %x \n",cmd);
+				
+				ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
+
+
+			} else {
+				//Tx data
+				dev_dbg(i2c_dev->dev, "(-->) xfer byte data index[%02x]:%02x  \n",i2c_dev->master_xfer_cnt, *(xfer_buf + i2c_dev->master_xfer_cnt));
+				ast_i2c_write(i2c_dev, *(xfer_buf + i2c_dev->master_xfer_cnt), I2C_BYTE_BUF_REG);
+				if((i2c_dev->xfer_last == 1) && (i2c_dev->master_xfer_cnt + 1 == i2c_dev->master_msgs->len)) {
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+										~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);				
+					ast_i2c_write(i2c_dev, AST_I2CD_M_TX_CMD | AST_I2CD_M_STOP_CMD, I2C_CMD_REG);
+				} else {
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+										AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);			
+					ast_i2c_write(i2c_dev, AST_I2CD_M_TX_CMD, I2C_CMD_REG);
+				}
+			}
+					
+		} else {
+			//should send next msg 
+			if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
+				printk("CNT ERROR \n");
+			
+			dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
+			i2c_dev->cmd_err = 0;
+			complete(&i2c_dev->cmd_complete);		
+			
+		}
+	}
+		
+}
+
+static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
+{
+	u32 xfer_len;
+	int i;
+	u8 *rx_buf;
+	
+	dev_dbg(i2c_dev->dev, "ast_i2c_slave_xfer_done [%d]\n",i2c_dev->slave_xfer_mode);	
+
+	if (i2c_dev->slave_msgs->flags & I2C_M_RD) {
+		//tx done , only check tx count ...
+		if(i2c_dev->master_xfer_mode == BYTE_XFER) {
+			xfer_len = 1;
+		} else if (i2c_dev->master_xfer_mode == BUFF_XFER) {
+			xfer_len = AST_I2CD_TX_DATA_BUF_GET(ast_i2c_read(i2c_dev, I2C_BUF_CTRL_REG));
+			xfer_len++;
+			dev_dbg(i2c_dev->dev,"S tx buff done len %d \n",xfer_len);
+		} else {
+			//DMA mode
+			xfer_len = ast_i2c_read(i2c_dev, I2C_DMA_LEN_REG);
+			if(xfer_len == 0)
+				xfer_len = i2c_dev->slave_xfer_len;
+			else
+				xfer_len = i2c_dev->slave_xfer_len - xfer_len - 1;
+
+			dev_dbg(i2c_dev->dev,"S tx rx dma done len %d \n",xfer_len);
+		}
+
+	} else {
+		//rx done
+		if(i2c_dev->slave_xfer_mode == BYTE_XFER) {
+			//TODO
+			xfer_len = 1;
+			if(i2c_dev->slave_event == I2C_SLAVE_EVENT_STOP) {
+				i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt] = 0;
+				i2c_dev->slave_msgs->len = i2c_dev->slave_xfer_cnt;
+			} else {
+				i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt] = ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) >> 8;
+			}
+			dev_dbg(i2c_dev->dev,"rx buff %d, [%x] \n",i2c_dev->slave_xfer_cnt ,i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt]);
+		} else if (i2c_dev->master_xfer_mode == BUFF_XFER) {
+			xfer_len = AST_I2CD_RX_BUF_ADDR_GET(ast_i2c_read(i2c_dev, I2C_BUF_CTRL_REG));
+			if(xfer_len == 0)
+				xfer_len = AST_I2C_PAGE_SIZE;
+	
+			dev_dbg(i2c_dev->dev,"rx buff done len %d \n",xfer_len);
+			
+			rx_buf = (u8 *)i2c_dev->req_page->page_addr;
+	
+			for(i=0;i<xfer_len;i++) {
+				i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i] = rx_buf[i];
+				dev_dbg(i2c_dev->dev,"%d, [%x] \n",i2c_dev->slave_xfer_cnt+i ,i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i]);
+			}
+		
+		} else {
+			//RX DMA DOWN
+			xfer_len = ast_i2c_read(i2c_dev, I2C_DMA_LEN_REG);
+			if(xfer_len == 0)
+				xfer_len = i2c_dev->slave_xfer_len;
+			else
+				xfer_len = i2c_dev->slave_xfer_len - xfer_len - 1;
+			
+			dev_dbg(i2c_dev->dev, " rx dma done len %d \n", xfer_len);
+			
+			for(i=0;i<xfer_len;i++) {
+				i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i] = i2c_dev->dma_buf[i];
+				dev_dbg(i2c_dev->dev,"%d, [%x] \n",i2c_dev->slave_xfer_cnt+i ,i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i]);
+			}
+		}
+	
+	}
+
+	if(xfer_len !=i2c_dev->slave_xfer_len) {
+		//TODO..
+		printk(" **slave xfer error ====\n");
+		//should goto stop....
+	} else
+		i2c_dev->slave_xfer_cnt += i2c_dev->slave_xfer_len; 
+
+
+	if((i2c_dev->slave_event == I2C_SLAVE_EVENT_NACK) || (i2c_dev->slave_event == I2C_SLAVE_EVENT_STOP)) {
+#ifdef CONFIG_AST_I2C_SLAVE_RDWR
+			ast_i2c_slave_rdwr_xfer(i2c_dev);
+#else
+			i2c_dev->ast_i2c_data->slave_xfer(i2c_dev->slave_event, &(i2c_dev->slave_msgs));
+#endif				
+		i2c_dev->slave_xfer_cnt = 0;
+	} else {
+		if(i2c_dev->slave_xfer_cnt == i2c_dev->slave_msgs->len)	{
+			dev_dbg(i2c_dev->dev,"slave next msgs \n"); 	
+#ifdef CONFIG_AST_I2C_SLAVE_RDWR
+			ast_i2c_slave_rdwr_xfer(i2c_dev);
+#else
+			i2c_dev->ast_i2c_data->slave_xfer(i2c_dev->slave_event, &(i2c_dev->slave_msgs));
+#endif			
+
+			i2c_dev->slave_xfer_cnt = 0;
+		} 
+		i2c_dev->do_slave_xfer(i2c_dev);
+	}
+
+
+	if(AST_I2CD_IDLE == i2c_dev->state) {
+		dev_dbg(i2c_dev->dev,"** Slave go IDLE **\n");		
+		i2c_dev->slave_operation = 0;
+	
+		if(i2c_dev->slave_xfer_mode == BUFF_XFER) {
+			i2c_dev->ast_i2c_data->free_pool_buff_page(i2c_dev->req_page);
+		} 
+		
+	} 
+	
+}
+
+//TX/Rx Done
+static void ast_i2c_master_xfer_done(struct ast_i2c_dev *i2c_dev)
+{
+	u32 xfer_len;
+	int i;
+	u8 *pool_buf;
+
+	dev_dbg(i2c_dev->dev, "ast_i2c_master_xfer_done mode[%d]\n",i2c_dev->master_xfer_mode);	
+		
+	if (i2c_dev->master_msgs->flags & I2C_M_RD) {
+		if(i2c_dev->master_xfer_cnt == -1) {
+			xfer_len = 1;
+			goto next_xfer;
+		}
+		if(i2c_dev->master_xfer_mode == BYTE_XFER) {
+			if ((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+				i2c_dev->master_msgs->len += (ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) & AST_I2CD_RX_BYTE_BUFFER) >> 8; 
+				i2c_dev->blk_r_flag = 1;
+				dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);			
+			}
+			xfer_len = 1;
+			i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt] = (ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) & AST_I2CD_RX_BYTE_BUFFER) >> 8;
+		} else if (i2c_dev->master_xfer_mode == BUFF_XFER) {
+			pool_buf = (u8 *)i2c_dev->req_page->page_addr;
+			xfer_len = AST_I2CD_RX_BUF_ADDR_GET(ast_i2c_read(i2c_dev, I2C_BUF_CTRL_REG));
+			
+			if(xfer_len == 0)
+				xfer_len = AST_I2C_PAGE_SIZE;
+
+			for(i = 0; i< xfer_len; i++) {
+				i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i] = pool_buf[i];
+				dev_dbg(i2c_dev->dev, "rx %d buff[%x]\n",i2c_dev->master_xfer_cnt+i, i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt+i]);
+			}
+
+			if ((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+				i2c_dev->master_msgs->len += pool_buf[0];
+				i2c_dev->blk_r_flag = 1;
+				dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);			
+			}
+		} else {
+			//DMA Mode
+			xfer_len = ast_i2c_read(i2c_dev, I2C_DMA_LEN_REG);
+
+			if(xfer_len == 0)
+				xfer_len = i2c_dev->master_xfer_len;
+			else
+				xfer_len = i2c_dev->master_xfer_len - xfer_len - 1;
+
+			for(i = 0; i < xfer_len; i++) {
+				i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i] = i2c_dev->dma_buf[i];
+				dev_dbg(i2c_dev->dev, "buf[%x] \n", i2c_dev->dma_buf[i]);
+				dev_dbg(i2c_dev->dev, "buf[%x] \n", i2c_dev->dma_buf[i+1]);
+			}
+	
+			if ((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+					i2c_dev->master_msgs->len += i2c_dev->dma_buf[0];
+					i2c_dev->blk_r_flag = 1;
+					dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);			
+			}
+			
+		}
+
+	}else {
+		if(i2c_dev->master_xfer_mode == BYTE_XFER) {
+			xfer_len = 1;
+		} else if(i2c_dev->master_xfer_mode == BUFF_XFER) {
+			xfer_len = AST_I2CD_TX_DATA_BUF_GET(ast_i2c_read(i2c_dev, I2C_BUF_CTRL_REG));
+			xfer_len++;
+			dev_dbg(i2c_dev->dev,"tx buff done len %d \n",xfer_len);
+		} else {
+			//DMA
+			xfer_len = ast_i2c_read(i2c_dev, I2C_DMA_LEN_REG);
+			if(xfer_len == 0)
+				xfer_len = i2c_dev->master_xfer_len;
+			else
+				xfer_len = i2c_dev->master_xfer_len - xfer_len - 1;
+
+			dev_dbg(i2c_dev->dev,"tx dma done len %d \n",xfer_len);
+		}
+	}
+
+next_xfer:
+
+	if(xfer_len !=i2c_dev->master_xfer_len) {
+		//TODO..
+		printk(" ** xfer error \n");
+		//should goto stop....
+		i2c_dev->cmd_err = 1;
+		goto done_out;
+	} else
+		i2c_dev->master_xfer_cnt += i2c_dev->master_xfer_len; 
+
+	if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len) {
+		dev_dbg(i2c_dev->dev,"do next cnt \n");
+		i2c_dev->do_master_xfer(i2c_dev);
+	} else {
+#if 0	
+		int i;		
+		printk(" ===== \n");
+		for(i=0;i<i2c_dev->master_msgs->len;i++)
+			printk("rx buf i,[%x]\n",i,i2c_dev->master_msgs->buf[i]);
+		printk(" ===== \n");	
+#endif		
+		i2c_dev->cmd_err = 0;
+
+done_out:
+		dev_dbg(i2c_dev->dev,"msgs complete \n");
+		complete(&i2c_dev->cmd_complete);					
+	}
+}
+
+static void ast_i2c_slave_addr_match(struct ast_i2c_dev *i2c_dev)
+{
+	u8 match;
+
+	i2c_dev->slave_operation = 1;
+	i2c_dev->slave_xfer_cnt = 0;
+	match = ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) >> 8;
+	i2c_dev->slave_msgs->buf[0] = match;
+	dev_dbg(i2c_dev->dev, "S Start Addr match [%x] \n",match);
+
+	
+	if(match & 1) {
+		i2c_dev->slave_event = I2C_SLAVE_EVENT_START_READ;
+	} else {
+		i2c_dev->slave_event = I2C_SLAVE_EVENT_START_WRITE;
+	}
+
+#ifdef CONFIG_AST_I2C_SLAVE_RDWR
+	ast_i2c_slave_rdwr_xfer(i2c_dev);
+	i2c_dev->slave_msgs->buf[0] = match;
+	i2c_dev->slave_xfer_cnt = 1;
+#else
+	i2c_dev->ast_i2c_data->slave_xfer(i2c_dev->slave_event, &(i2c_dev->slave_msgs));
+	i2c_dev->slave_xfer_cnt = 0;
+#endif			
+
+	//request
+	if(i2c_dev->ast_i2c_data->slave_dma == BYTE_MODE)
+		i2c_dev->do_slave_xfer = ast_i2c_do_byte_xfer;
+	else if (i2c_dev->ast_i2c_data->slave_dma == DMA_MODE)
+		i2c_dev->do_slave_xfer = ast_i2c_do_dma_xfer;
+	else {
+		if(i2c_dev->ast_i2c_data->request_pool_buff_page(&(i2c_dev->req_page)) == 0)
+			i2c_dev->do_slave_xfer = ast_i2c_do_pool_xfer;
+		else								
+			i2c_dev->do_slave_xfer = ast_i2c_do_byte_xfer;
+	}
+
+	i2c_dev->do_slave_xfer(i2c_dev);
+
+}
+
+static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+{
+	u32 sts;	
+
+	struct ast_i2c_dev *i2c_dev = dev_id;
+	u32 isr_sts = readl(i2c_dev->ast_i2c_data->reg_gr);
+
+	if(!(isr_sts & (1<< i2c_dev->bus_id)))
+		return IRQ_NONE;
+
+	i2c_dev->state = (ast_i2c_read(i2c_dev,I2C_CMD_REG) >> 19) & 0xf;
+	sts = ast_i2c_read(i2c_dev,I2C_INTR_STS_REG);
+//	printk("ISR : %x , sts [%x]\n",sts , xfer_sts);	
+//	dev_dbg(i2c_dev->dev,"ISR : %x , sts [%x]\n",sts , xfer_sts);
+
+//	dev_dbg(i2c_dev->dev,"sts machine %x, slave_op %d \n", xfer_sts,i2c_dev->slave_operation);
+
+	if(AST_I2CD_INTR_STS_SMBUS_ALT & sts) {
+		dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_SMBUS_ALT= %x\n",sts);
+		//Disable ALT INT
+		ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev, I2C_INTR_CTRL_REG) &
+					~AST_I2CD_SMBUS_ALT_INTR_EN,
+					I2C_INTR_CTRL_REG);
+		ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_SMBUS_ALT, I2C_INTR_STS_REG);
+		ast_master_alert_recv(i2c_dev);
+		sts &= ~AST_I2CD_SMBUS_ALT_INTR_EN; 
+	}
+	
+	switch(sts) {
+		case AST_I2CD_INTR_STS_TX_ACK:
+			if(i2c_dev->slave_operation == 1) {
+				i2c_dev->slave_event = I2C_SLAVE_EVENT_READ;
+				ast_i2c_slave_xfer_done(i2c_dev);
+				dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_TX_ACK = %x\n",sts);
+				ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK, I2C_INTR_STS_REG);		   
+			} else {
+				dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_ACK = %x\n",sts);
+				ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK, I2C_INTR_STS_REG);
+				ast_i2c_master_xfer_done(i2c_dev);
+			}
+			break;
+		case AST_I2CD_INTR_STS_TX_ACK | AST_I2CD_INTR_STS_NORMAL_STOP:
+				if((i2c_dev->xfer_last == 1) && (i2c_dev->slave_operation == 0)) {
+					dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_ACK | AST_I2CD_INTR_STS_NORMAL_STOP= %x\n",sts);
+					ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK | AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
+					//take care
+					ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+										AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+					ast_i2c_master_xfer_done(i2c_dev);
+					
+				} else {
+					printk("TODO ...\n");
+				}
+			break;
+
+		case AST_I2CD_INTR_STS_TX_NAK:
+			if(i2c_dev->slave_operation == 1) {
+				i2c_dev->slave_event = I2C_SLAVE_EVENT_NACK;
+				ast_i2c_slave_xfer_done(i2c_dev);
+				dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_TX_NAK = %x\n",sts);
+				ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK, I2C_INTR_STS_REG); 
+				
+			} else {
+				dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_NAK = %x\n",sts);
+				ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK, I2C_INTR_STS_REG);
+				if(i2c_dev->master_msgs->flags == I2C_M_IGNORE_NAK) {
+					dev_dbg(i2c_dev->dev, "I2C_M_IGNORE_NAK next send\n");
+					i2c_dev->cmd_err = 0;
+				} else {
+					dev_dbg(i2c_dev->dev, "NAK error\n");
+					i2c_dev->cmd_err = AST_I2CD_INTR_STS_TX_NAK;
+				}
+				complete(&i2c_dev->cmd_complete);
+			}
+			break;
+
+		case AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_NORMAL_STOP:
+			if(i2c_dev->slave_operation == 1) {
+				printk("SLAVE TODO .... \n");
+				
+			} else {
+				dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_NAK| AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
+				ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
+				dev_dbg(i2c_dev->dev, "M TX NAK | NORMAL STOP \n");
+				i2c_dev->cmd_err = AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_NORMAL_STOP;
+				complete(&i2c_dev->cmd_complete);
+			}
+			break;
+
+		//Issue : Workaround for I2C slave mode 
+		case AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_SLAVE_MATCH:
+			if(i2c_dev->slave_operation == 1) {
+				i2c_dev->slave_event = I2C_SLAVE_EVENT_NACK;
+				ast_i2c_slave_xfer_done(i2c_dev);
+				ast_i2c_slave_addr_match(i2c_dev);
+				ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_SLAVE_MATCH , I2C_INTR_STS_REG); 
+			} else {
+				printk("ERROR !!!!\n");
+			}
+			break;
+		case AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH:
+			ast_i2c_slave_addr_match(i2c_dev);
+			dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH = %x\n",sts);	
+			ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH, I2C_INTR_STS_REG);
+			break;
+			
+		case AST_I2CD_INTR_STS_RX_DOWN:
+			if(i2c_dev->slave_operation == 1) {
+				i2c_dev->slave_event = I2C_SLAVE_EVENT_WRITE;
+				ast_i2c_slave_xfer_done(i2c_dev);
+				dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_RX_DOWN = %x\n",sts);
+				ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN, I2C_INTR_STS_REG);					
+			} else {
+				dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_RX_DOWN = %x\n",sts);
+				ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN, I2C_INTR_STS_REG);
+				ast_i2c_master_xfer_done(i2c_dev);
+				
+			}
+			break;
+			
+		case AST_I2CD_INTR_STS_NORMAL_STOP:
+			if(i2c_dev->slave_operation == 1) {
+				i2c_dev->slave_event = I2C_SLAVE_EVENT_STOP;
+				ast_i2c_slave_xfer_done(i2c_dev);
+				dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
+				ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);					
+				dev_dbg(i2c_dev->dev, "state [%x] \n",i2c_dev->state);
+			} else {							
+				dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
+				ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);			
+				i2c_dev->cmd_err = 0;
+				complete(&i2c_dev->cmd_complete);
+			}
+			break;
+		case (AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_NORMAL_STOP):
+			if((i2c_dev->xfer_last == 1) && (i2c_dev->slave_operation == 0)) {	
+				dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
+				ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
+				//take care
+				ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+									AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+				ast_i2c_master_xfer_done(i2c_dev);
+			} else {
+				printk("TODO .. .. ..\n");
+			}
+			break;
+		case AST_I2CD_INTR_STS_ARBIT_LOSS:
+			dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_ARBIT_LOSS = %x\n",sts);
+			ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_ARBIT_LOSS, I2C_INTR_STS_REG);
+			i2c_dev->cmd_err = AST_I2CD_INTR_STS_ARBIT_LOSS;
+			complete(&i2c_dev->cmd_complete);					
+			break;
+		case AST_I2CD_INTR_STS_ABNORMAL:
+			i2c_dev->cmd_err = AST_I2CD_INTR_STS_ABNORMAL;
+			complete(&i2c_dev->cmd_complete);					
+			break;
+		case AST_I2CD_INTR_STS_SCL_TO:
+			i2c_dev->cmd_err = AST_I2CD_INTR_STS_SCL_TO;
+			complete(&i2c_dev->cmd_complete);					
+			
+			break;
+ 		case AST_I2CD_INTR_STS_GCALL_ADDR:
+			i2c_dev->cmd_err = AST_I2CD_INTR_STS_GCALL_ADDR;
+			complete(&i2c_dev->cmd_complete);					
+
+			break;
+		case AST_I2CD_INTR_STS_SMBUS_DEF_ADDR:
+			break;
+		case AST_I2CD_INTR_STS_SMBUS_DEV_ALT:
+			
+			break;
+			
+		case AST_I2CD_INTR_STS_SMBUS_ARP_ADDR:
+			break;
+		case AST_I2CD_INTR_STS_SDA_DL_TO:
+			break;
+		case AST_I2CD_INTR_STS_BUS_RECOVER:
+			dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_BUS_RECOVER= %x\n",sts);
+			ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_BUS_RECOVER, I2C_INTR_STS_REG);
+			i2c_dev->cmd_err = 0;
+			complete(&i2c_dev->cmd_complete);				
+			break;
+		default:
+			if(sts)
+				printk("GR %x : No one care : %x, bus_id %d\n",i2c_dev->ast_i2c_data->reg_gr, sts, i2c_dev->bus_id);
+			return IRQ_NONE;
+	}
+
+	return IRQ_HANDLED;
+
+}
+
+static int ast_i2c_do_msgs_xfer(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msgs, int num)
+{
+	int i;
+	int ret = 1;	
+
+	//request
+	if(i2c_dev->ast_i2c_data->master_dma == BYTE_MODE)
+		i2c_dev->do_master_xfer = ast_i2c_do_byte_xfer;
+	else if (i2c_dev->ast_i2c_data->master_dma == DMA_MODE)
+		i2c_dev->do_master_xfer = ast_i2c_do_dma_xfer;
+	else {
+		if(i2c_dev->ast_i2c_data->request_pool_buff_page(&(i2c_dev->req_page)) == 0)
+			i2c_dev->do_master_xfer = ast_i2c_do_pool_xfer;
+		else								
+			i2c_dev->do_master_xfer = ast_i2c_do_byte_xfer;
+	}
+
+//	printk("start xfer ret = %d \n",ret);
+
+	for (i=0; i < num; i++) {
+		i2c_dev->blk_r_flag = 0;
+		i2c_dev->master_msgs = &msgs[i];
+		if(num == i+1)
+			i2c_dev->xfer_last = 1;
+		else
+			i2c_dev->xfer_last = 0;
+
+		i2c_dev->blk_r_flag = 0;
+		init_completion(&i2c_dev->cmd_complete);
+
+		if(i2c_dev->master_msgs->flags & I2C_M_NOSTART)
+			i2c_dev->master_xfer_cnt = 0;
+		else
+			i2c_dev->master_xfer_cnt = -1;
+
+		i2c_dev->do_master_xfer(i2c_dev);
+
+		ret = wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
+													   i2c_dev->adap.timeout*HZ);
+	
+		if (ret == 0) {
+			dev_dbg(i2c_dev->dev, "controller timed out\n");
+			i2c_dev->state = (ast_i2c_read(i2c_dev,I2C_CMD_REG) >> 19) & 0xf;
+//			printk("sts [%x], isr sts [%x] \n",i2c_dev->state, ast_i2c_read(i2c_dev,I2C_INTR_STS_REG));
+			ret = -ETIMEDOUT;
+			goto stop;
+		}
+		
+		if(i2c_dev->cmd_err != 0) {
+			ret = -EAGAIN;
+			goto stop;
+		}
+		
+	}
+
+	if(i2c_dev->cmd_err == 0) {
+		ret = num;
+		goto out;
+		
+	}
+stop:
+	init_completion(&i2c_dev->cmd_complete);
+	ast_i2c_write(i2c_dev, AST_I2CD_M_STOP_CMD, I2C_CMD_REG);
+	wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
+											   i2c_dev->adap.timeout*HZ);
+
+out:
+	//Free ..
+	if(i2c_dev->master_xfer_mode == BUFF_XFER) {
+		i2c_dev->ast_i2c_data->free_pool_buff_page(i2c_dev->req_page);
+		
+	} 
+	dev_dbg(i2c_dev->dev, "end xfer ret = %d, xfer mode[%d]\n",ret, i2c_dev->master_xfer_mode);
+	return ret;
+
+}
+
+static int ast_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+	struct ast_i2c_dev *i2c_dev = adap->algo_data;
+	int ret, i;
+	int sts;
+
+	sts = ast_i2c_read(i2c_dev,I2C_CMD_REG);
+	dev_dbg(i2c_dev->dev, "state[%x],SCL[%d],SDA[%d],BUS[%d]\n", (sts >> 19) & 0xf, (sts >> 18) & 0x1,(sts >> 17) & 0x1,(sts >> 16) & 1);
+	/*
+	 * Wait for the bus to become free.
+	 */
+	
+	ret = ast_i2c_wait_bus_not_busy(i2c_dev);
+	if (ret) {
+		dev_err(&i2c_dev->adap.dev, "i2c_ast: timeout waiting for bus free\n");
+		goto out;
+	}
+
+	for (i = adap->retries; i >= 0; i--) {
+
+		ret = ast_i2c_do_msgs_xfer(i2c_dev, msgs, num);
+		if (ret != -EAGAIN)
+			goto out;
+		dev_dbg(&adap->dev, "Retrying transmission [%d]\n",i);
+		udelay(100);
+	}
+		
+	ret = -EREMOTEIO;
+out:
+
+	return ret;
+}
+
+static u32 ast_i2c_functionality(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+static const struct i2c_algorithm i2c_ast_algorithm = {
+	.master_xfer	= ast_i2c_xfer,
+#ifdef CONFIG_AST_I2C_SLAVE_RDWR		
+	.slave_xfer		= ast_i2c_slave_xfer,
+#endif	
+	.functionality	= ast_i2c_functionality,
+};
+
+static int ast_i2c_probe(struct platform_device *pdev)
+{
+	struct ast_i2c_dev *i2c_dev;
+	struct resource *res;
+	int ret;
+
+	dev_dbg(&pdev->dev, "ast_i2c_probe \n");
+
+	i2c_dev = kzalloc(sizeof(struct ast_i2c_dev), GFP_KERNEL);
+	if (!i2c_dev) {
+		ret = -ENOMEM;
+		goto err_no_mem;
+	}
+
+	i2c_dev->ast_i2c_data = pdev->dev.platform_data;
+	if(i2c_dev->ast_i2c_data->master_dma == BUFF_MODE) {
+		dev_dbg(&pdev->dev, "use buffer pool mode 256\n");	
+		
+	} else if ((i2c_dev->ast_i2c_data->master_dma == DMA_MODE) || (i2c_dev->ast_i2c_data->slave_dma == DMA_MODE)) {
+		dev_dbg(&pdev->dev, "use dma mode \n");	
+		if (!i2c_dev->dma_buf) {
+			i2c_dev->dma_buf = dma_alloc_coherent(NULL, AST_I2C_DMA_SIZE, &i2c_dev->dma_addr, GFP_KERNEL);
+			if (!i2c_dev->dma_buf) {
+				printk("unable to allocate tx Buffer memory\n");
+				ret = -ENOMEM;
+				goto err_no_dma;	
+			}
+			if(i2c_dev->dma_addr%4 !=0) {
+				printk("not 4 byte boundary \n");
+				ret = -ENOMEM;
+				goto err_no_dma;	
+			}				
+//			printk("dma_buf = [0x%x] dma_addr = [0x%x], please check 4byte boundary \n",i2c_dev->dma_buf,i2c_dev->dma_addr);	
+			memset (i2c_dev->dma_buf, 0, AST_I2C_DMA_SIZE);
+		}
+
+	} else {
+		//master_mode 0: use byte mode
+		dev_dbg(&pdev->dev, "use default byte mode \n");
+	}
+		
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (NULL == res) {
+		dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
+		ret = -ENOENT;
+		goto err_no_io_res;
+	}
+	if (!request_mem_region(res->start, resource_size(res), res->name)) {
+        dev_err(&pdev->dev, "cannot reserved region\n");
+        ret = -ENXIO;
+        goto err_no_io_res;
+	}
+
+	i2c_dev->reg_base = ioremap(res->start, resource_size(res));
+	if (!i2c_dev->reg_base) {
+		ret = -EIO;
+		goto release_mem;
+	}
+
+	i2c_dev->irq = platform_get_irq(pdev, 0);
+	if (i2c_dev->irq < 0) {
+		dev_err(&pdev->dev, "no irq specified\n");
+		ret = -ENOENT;
+		goto ereqirq;
+	}
+
+	i2c_dev->dev = &pdev->dev;
+
+#if defined (CONFIG_ARCH_AST1070)
+	if(i2c_dev->irq == IRQ_C0_I2C) {
+		i2c_dev->bus_id = pdev->id - NUM_BUS;
+		dev_dbg(&pdev->dev, "C0 :: pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);
+#if (CONFIG_AST1070_NR >= 2)		
+	} else if(i2c_dev->irq == IRQ_C1_I2C) {
+		i2c_dev->bus_id = pdev->id - (NUM_BUS + 8);
+		dev_dbg(&pdev->dev, "C1 :: pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);			
+#endif		
+	} else {
+		i2c_dev->bus_id = pdev->id;
+		dev_dbg(&pdev->dev, "AST pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);
+	}
+#else
+	i2c_dev->bus_id = pdev->id;
+#endif
+
+ 	/* Initialize the I2C adapter */
+	i2c_dev->adap.owner   = THIS_MODULE;
+//TODO
+	i2c_dev->adap.retries = 0;	
+
+//	i2c_dev->adap.retries = 3;	
+
+	i2c_dev->adap.timeout = 5; 
+
+	i2c_dev->master_xfer_mode = BYTE_XFER;	
+
+	/*
+	 * If "pdev->id" is negative we consider it as zero.
+	 * The reason to do so is to avoid sysfs names that only make
+	 * sense when there are multiple adapters.
+	 */
+	i2c_dev->adap.nr = pdev->id != -1 ? pdev->id : 0;
+	snprintf(i2c_dev->adap.name, sizeof(i2c_dev->adap.name), "ast_i2c.%u",
+		 i2c_dev->adap.nr);
+
+	i2c_dev->slave_operation = 0;
+	i2c_dev->blk_r_flag = 0; 
+	i2c_dev->adap.algo = &i2c_ast_algorithm;
+
+	ret = request_irq(i2c_dev->irq, i2c_ast_handler, IRQF_SHARED,
+			  i2c_dev->adap.name, i2c_dev);
+	if (ret) {
+		printk(KERN_INFO "I2C: Failed request irq %d\n", i2c_dev->irq);
+		goto ereqirq;
+	}
+
+	ast_i2c_dev_init(i2c_dev);
+
+#ifdef CONFIG_AST_I2C_SLAVE_RDWR
+	ast_i2c_slave_buff_init(i2c_dev);
+#endif
+
+	i2c_dev->adap.algo_data = i2c_dev;
+	i2c_dev->adap.dev.parent = &pdev->dev;
+
+	i2c_dev->adap.id = pdev->id;
+
+	ret = i2c_add_numbered_adapter(&i2c_dev->adap);
+	if (ret < 0) {
+		printk(KERN_INFO "I2C: Failed to add bus\n");
+		goto eadapt;
+	}
+
+	platform_set_drvdata(pdev, i2c_dev);
+
+	printk(KERN_INFO "I2C: %s: AST I2C adapter [%d khz]\n",
+	       i2c_dev->adap.dev.bus_id,i2c_dev->ast_i2c_data->bus_clk/1000);
+
+	return 0;
+
+eadapt:
+	free_irq(i2c_dev->irq, i2c_dev);
+ereqirq:
+	iounmap(i2c_dev->reg_base);
+
+release_mem:
+	release_mem_region(res->start, resource_size(res));
+err_no_io_res:
+err_no_dma:
+	kfree(i2c_dev);
+
+err_no_mem:
+	return ret;
+}
+
+static int ast_i2c_remove(struct platform_device *pdev)
+{
+	struct ast_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+	struct resource *res;
+
+	platform_set_drvdata(pdev, NULL);
+	i2c_del_adapter(&i2c_dev->adap);
+	
+	free_irq(i2c_dev->irq, i2c_dev);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	iounmap(i2c_dev->reg_base);
+	release_mem_region(res->start, res->end - res->start + 1);
+
+	kfree(i2c_dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ast_i2c_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	//TODO
+//	struct ast_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+	return 0;
+}
+
+static int ast_i2c_resume(struct platform_device *pdev)
+{
+	//TODO
+//	struct ast_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+	//Should reset i2c ??? 
+	return 0;
+}
+#else
+#define ast_i2c_suspend        NULL
+#define ast_i2c_resume         NULL
+#endif
+
+static struct platform_driver i2c_ast_driver = {
+	.probe			= ast_i2c_probe,
+	.remove 		= __devexit_p(ast_i2c_remove),
+    .suspend        = ast_i2c_suspend,
+    .resume         = ast_i2c_resume,
+    .driver         = {
+            .name   = "ast-i2c",
+            .owner  = THIS_MODULE,
+    },
+};
+
+static int __init ast_i2c_init(void)
+{
+	return platform_driver_register(&i2c_ast_driver);
+}
+
+static void __exit ast_i2c_exit(void)
+{
+	platform_driver_unregister(&i2c_ast_driver);
+}
+//TODO : check module init sequence
+module_init(ast_i2c_init);
+module_exit(ast_i2c_exit);
+
+MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
+MODULE_DESCRIPTION("ASPEED AST I2C Bus Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ast_i2c");
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index feb00df..5ced92c 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1063,6 +1063,32 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
 }
 EXPORT_SYMBOL(i2c_transfer);
 
+#ifdef CONFIG_AST_I2C_SLAVE_RDWR
+int i2c_slave_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
+{
+	unsigned long orig_jiffies;
+	int ret, try;
+
+	if (adap->algo->slave_xfer) {
+#ifdef DEBUG
+		dev_dbg(&adap->dev, "slave_xfer %c, addr=0x%02x, "
+			"len=%d\n", (msgs->flags & I2C_S_RD)
+			? 'R' : 'W', msgs->addr, msgs->len);
+#endif
+		i2c_lock_adapter(adap);
+		ret = adap->algo->slave_xfer(adap, msgs);
+		i2c_unlock_adapter(adap);
+
+		return ret;
+	} else {
+		dev_dbg(&adap->dev, "I2C level transfers not supported\n");
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL(i2c_slave_transfer);
+
+#endif
+
 /**
  * i2c_master_send - issue a single I2C message in master transmit mode
  * @client: Handle to slave device
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index c171988..7d1f7e9 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -37,6 +37,10 @@
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 
+#ifdef CONFIG_AST_I2C_SLAVE_RDWR
+#include <asm/arch/ast_i2c.h>
+#endif
+
 static struct i2c_driver i2cdev_driver;
 
 /*
@@ -415,6 +419,11 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	case I2C_RDWR:
 		return i2cdev_ioctl_rdrw(client, arg);
 
+#ifdef CONFIG_AST_I2C_SLAVE_RDWR
+	case I2C_SLAVE_RDWR:
+		return i2cdev_ioctl_slave_rdrw(client->adapter, (struct i2c_msg __user *)arg);
+#endif		
+
 	case I2C_SMBUS:
 		return i2cdev_ioctl_smbus(client, arg);
 
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index fdd7c76..1928a42 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -113,20 +113,29 @@ static int mmc_decode_cid(struct mmc_card *card)
 static int mmc_decode_csd(struct mmc_card *card)
 {
 	struct mmc_csd *csd = &card->csd;
-	unsigned int e, m, csd_struct;
+	unsigned int e, m;
 	u32 *resp = card->raw_csd;
 
 	/*
 	 * We only understand CSD structure v1.1 and v1.2.
 	 * v1.2 has extra information in bits 15, 11 and 10.
+	 * We also support eMMC v4.4 & v4.41.
 	 */
+#if 0	 
 	csd_struct = UNSTUFF_BITS(resp, 126, 2);
 	if (csd_struct != 1 && csd_struct != 2) {
 		printk(KERN_ERR "%s: unrecognised CSD structure version %d\n",
 			mmc_hostname(card->host), csd_struct);
 		return -EINVAL;
 	}
-
+#else
+	csd->structure = UNSTUFF_BITS(resp, 126, 2);
+	if (csd->structure == 0) {
+		printk(KERN_ERR "%s: unrecognised CSD structure version %d\n",
+			mmc_hostname(card->host), csd->structure);
+		return -EINVAL;
+	}
+#endif
 	csd->mmca_vsn	 = UNSTUFF_BITS(resp, 122, 4);
 	m = UNSTUFF_BITS(resp, 115, 4);
 	e = UNSTUFF_BITS(resp, 112, 3);
@@ -207,6 +216,7 @@ static int mmc_read_ext_csd(struct mmc_card *card)
 		goto out;
 	}
 
+#if 0
 	ext_csd_struct = ext_csd[EXT_CSD_REV];
 	if (ext_csd_struct > 2) {
 		printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
@@ -215,7 +225,7 @@ static int mmc_read_ext_csd(struct mmc_card *card)
 		err = -EINVAL;
 		goto out;
 	}
-
+	
 	if (ext_csd_struct >= 2) {
 		card->ext_csd.sectors =
 			ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
@@ -224,7 +234,8 @@ static int mmc_read_ext_csd(struct mmc_card *card)
 			ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
 		if (card->ext_csd.sectors)
 			mmc_card_set_blockaddr(card);
-	}
+	}	
+
 
 	switch (ext_csd[EXT_CSD_CARD_TYPE]) {
 	case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
@@ -239,8 +250,86 @@ static int mmc_read_ext_csd(struct mmc_card *card)
 			"support any high-speed modes.\n",
 			mmc_hostname(card->host));
 		goto out;
+	}	
+#else
+	/* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */
+	if (card->csd.structure == 3) {
+		int ext_csd_struct = ext_csd[EXT_CSD_STRUCTURE];
+		if (ext_csd_struct > 2) {
+			printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
+				"version %d\n", mmc_hostname(card->host),
+					ext_csd_struct);
+			err = -EINVAL;
+			goto out;
+		}
 	}
 
+	card->ext_csd.rev = ext_csd[EXT_CSD_REV];
+	if (card->ext_csd.rev > 6) {
+		printk(KERN_ERR "%s: unrecognised EXT_CSD revision %d\n",
+			mmc_hostname(card->host), card->ext_csd.rev);
+		err = -EINVAL;
+		goto out;
+	}
+
+	if (card->ext_csd.rev >= 2) {
+		card->ext_csd.sectors =
+			ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
+			ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
+			ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
+			ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
+
+		/* Cards with density > 2GiB are sector addressed */
+		if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512)
+			mmc_card_set_blockaddr(card);
+	}
+
+	switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
+	case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
+		card->ext_csd.hs_max_dtr = 52000000;
+		break;
+	case EXT_CSD_CARD_TYPE_26:
+		card->ext_csd.hs_max_dtr = 26000000;
+		break;
+	default:
+		/* MMC v4 spec says this cannot happen */
+		printk(KERN_WARNING "%s: card is mmc v4 but doesn't "
+			"support any high-speed modes.\n",
+			mmc_hostname(card->host));
+	}
+
+	if (card->ext_csd.rev >= 3) {
+		u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT];
+
+		/* Sleep / awake timeout in 100ns units */
+		if (sa_shift > 0 && sa_shift <= 0x17)
+			card->ext_csd.sa_timeout =
+					1 << ext_csd[EXT_CSD_S_A_TIMEOUT];
+		card->ext_csd.erase_group_def =
+			ext_csd[EXT_CSD_ERASE_GROUP_DEF];
+		card->ext_csd.hc_erase_timeout = 300 *
+			ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
+		card->ext_csd.hc_erase_size =
+			ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10;
+	}
+
+	if (card->ext_csd.rev >= 4) {
+		card->ext_csd.sec_trim_mult =
+			ext_csd[EXT_CSD_SEC_TRIM_MULT];
+		card->ext_csd.sec_erase_mult =
+			ext_csd[EXT_CSD_SEC_ERASE_MULT];
+		card->ext_csd.sec_feature_support =
+			ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
+		card->ext_csd.trim_timeout = 300 *
+			ext_csd[EXT_CSD_TRIM_MULT];
+	}
+
+	if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
+		card->erased_byte = 0xFF;
+	else
+		card->erased_byte = 0x0;
+#endif
+
 out:
 	kfree(ext_csd);
 
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index dfa585f..ce66df5 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -37,6 +37,17 @@ config MMC_SDHCI
 
 	  If unsure, say N.
 
+config MMC_AST
+	tristate "ASPEED Secure Digital Host Controller Interface support"
+	depends on HAS_DMA
+	help
+	  This selects the ASPEED Secure Digital Host Controller Interface.
+
+	  If you have a controller with this interface, say Y or M here. You
+	  also need to enable an appropriate bus interface.
+
+	  If unsure, say N.
+
 config MMC_SDHCI_PCI
 	tristate "SDHCI support on PCI bus"
 	depends on MMC_SDHCI && PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index c794cc5..5078ba2 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_MMC_ARMMMCI)	+= mmci.o
 obj-$(CONFIG_MMC_PXA)		+= pxamci.o
 obj-$(CONFIG_MMC_IMX)		+= imxmmc.o
 obj-$(CONFIG_MMC_SDHCI)		+= sdhci.o
+obj-$(CONFIG_MMC_AST)		+= ast_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_PCI)	+= sdhci-pci.o
 obj-$(CONFIG_MMC_RICOH_MMC)	+= ricoh_mmc.o
 obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
diff --git a/drivers/mmc/host/ast_sdhci.c b/drivers/mmc/host/ast_sdhci.c
new file mode 100644
index 0000000..8b5d80d
--- /dev/null
+++ b/drivers/mmc/host/ast_sdhci.c
@@ -0,0 +1,1929 @@
+/*
+ *  aspeed_sdhci.c - ASPEED Secure Digital Host Controller Interface driver
+ *
+ * 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.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/highmem.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+#include <linux/platform_device.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+
+#include <linux/leds.h>
+
+#include <linux/mmc/host.h>
+
+#include <plat/ast_sdhci.h>
+
+
+#define DRIVER_NAME "ast_sdhci"
+
+#define DBG(f, x...) \
+	pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
+
+static unsigned int debug_quirks = 0;
+
+struct ast_sdhc_platform_data *ast_sdhc_info;
+
+static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *);
+static void sdhci_finish_data(struct sdhci_host *);
+
+static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
+static void sdhci_finish_command(struct sdhci_host *);
+
+static void sdhci_dumpregs(struct sdhci_host *host)
+{
+	printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n");
+
+	printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
+		readl(host->ioaddr + SDHCI_DMA_ADDRESS),
+		readw(host->ioaddr + SDHCI_HOST_VERSION));
+	printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
+		readw(host->ioaddr + SDHCI_BLOCK_SIZE),
+		readw(host->ioaddr + SDHCI_BLOCK_COUNT));
+	printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
+		readl(host->ioaddr + SDHCI_ARGUMENT),
+		readw(host->ioaddr + SDHCI_TRANSFER_MODE));
+	printk(KERN_DEBUG DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
+		readl(host->ioaddr + SDHCI_PRESENT_STATE),
+		readb(host->ioaddr + SDHCI_HOST_CONTROL));
+	printk(KERN_DEBUG DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
+		readb(host->ioaddr + SDHCI_POWER_CONTROL),
+		readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL));
+	printk(KERN_DEBUG DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
+		readb(host->ioaddr + SDHCI_WAKE_UP_CONTROL),
+		readw(host->ioaddr + SDHCI_CLOCK_CONTROL));
+	printk(KERN_DEBUG DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
+		readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL),
+		readl(host->ioaddr + SDHCI_INT_STATUS));
+	printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
+		readl(host->ioaddr + SDHCI_INT_ENABLE),
+		readl(host->ioaddr + SDHCI_SIGNAL_ENABLE));
+	printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
+		readw(host->ioaddr + SDHCI_ACMD12_ERR),
+		readw(host->ioaddr + SDHCI_SLOT_INT_STATUS));
+	printk(KERN_DEBUG DRIVER_NAME ": Caps:     0x%08x | Max curr: 0x%08x\n",
+		readl(host->ioaddr + SDHCI_CAPABILITIES),
+		readl(host->ioaddr + SDHCI_MAX_CURRENT));
+
+	printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
+}
+
+/*****************************************************************************\
+ *                                                                           *
+ * Low level functions                                                       *
+ *                                                                           *
+\*****************************************************************************/
+
+static void sdhci_reset(struct sdhci_host *host, u8 mask)
+{
+	unsigned long timeout;
+
+	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
+		if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
+			SDHCI_CARD_PRESENT))
+			return;
+	}
+
+	writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET);
+
+	if (mask & SDHCI_RESET_ALL)
+		host->clock = 0;
+
+	/* Wait max 100 ms */
+	timeout = 100;
+
+	/* hw clears the bit when it's done */
+	while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) {
+		if (timeout == 0) {
+			printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
+				mmc_hostname(host->mmc), (int)mask);
+			sdhci_dumpregs(host);
+			return;
+		}
+		timeout--;
+		mdelay(1);
+	}
+}
+
+static void sdhci_init(struct sdhci_host *host)
+{
+	u32 intmask;
+
+	sdhci_reset(host, SDHCI_RESET_ALL);
+
+	intmask = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
+		SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
+		SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
+		SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT |
+		SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL |
+		SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE |
+		SDHCI_INT_ADMA_ERROR;
+
+	writel(intmask, host->ioaddr + SDHCI_INT_ENABLE);
+	writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE);
+}
+
+static void sdhci_activate_led(struct sdhci_host *host)
+{
+	u8 ctrl;
+
+	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+	ctrl |= SDHCI_CTRL_LED;
+	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+}
+
+static void sdhci_deactivate_led(struct sdhci_host *host)
+{
+	u8 ctrl;
+
+	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+	ctrl &= ~SDHCI_CTRL_LED;
+	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+}
+
+#ifdef CONFIG_LEDS_CLASS
+static void sdhci_led_control(struct led_classdev *led,
+	enum led_brightness brightness)
+{
+	struct sdhci_host *host = container_of(led, struct sdhci_host, led);
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (brightness == LED_OFF)
+		sdhci_deactivate_led(host);
+	else
+		sdhci_activate_led(host);
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+#endif
+
+/*****************************************************************************\
+ *                                                                           *
+ * Core functions                                                            *
+ *                                                                           *
+\*****************************************************************************/
+
+static void sdhci_read_block_pio(struct sdhci_host *host)
+{
+	unsigned long flags;
+	size_t blksize, len, chunk;
+	u32 uninitialized_var(scratch);
+	u8 *buf;
+
+	DBG("PIO reading\n");
+
+	blksize = host->data->blksz;
+	chunk = 0;
+
+	local_irq_save(flags);
+
+	while (blksize) {
+		if (!sg_miter_next(&host->sg_miter))
+			BUG();
+
+		len = min(host->sg_miter.length, blksize);
+
+		blksize -= len;
+		host->sg_miter.consumed = len;
+
+		buf = host->sg_miter.addr;
+
+		while (len) {
+			if (chunk == 0) {
+				scratch = readl(host->ioaddr + SDHCI_BUFFER);
+				chunk = 4;
+			}
+
+			*buf = scratch & 0xFF;
+
+			buf++;
+			scratch >>= 8;
+			chunk--;
+			len--;
+		}
+	}
+
+	sg_miter_stop(&host->sg_miter);
+
+	local_irq_restore(flags);
+}
+
+static void sdhci_write_block_pio(struct sdhci_host *host)
+{
+	unsigned long flags;
+	size_t blksize, len, chunk;
+	u32 scratch;
+	u8 *buf;
+
+	DBG("PIO writing\n");
+
+	blksize = host->data->blksz;
+	chunk = 0;
+	scratch = 0;
+
+	local_irq_save(flags);
+
+	while (blksize) {
+		if (!sg_miter_next(&host->sg_miter))
+			BUG();
+
+		len = min(host->sg_miter.length, blksize);
+
+		blksize -= len;
+		host->sg_miter.consumed = len;
+
+		buf = host->sg_miter.addr;
+
+		while (len) {
+			scratch |= (u32)*buf << (chunk * 8);
+
+			buf++;
+			chunk++;
+			len--;
+
+			if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
+				writel(scratch, host->ioaddr + SDHCI_BUFFER);
+				chunk = 0;
+				scratch = 0;
+			}
+		}
+	}
+
+	sg_miter_stop(&host->sg_miter);
+
+	local_irq_restore(flags);
+}
+
+static void sdhci_transfer_pio(struct sdhci_host *host)
+{
+	u32 mask;
+
+	BUG_ON(!host->data);
+
+	if (host->blocks == 0)
+		return;
+
+	if (host->data->flags & MMC_DATA_READ)
+		mask = SDHCI_DATA_AVAILABLE;
+	else
+		mask = SDHCI_SPACE_AVAILABLE;
+
+	/*
+	 * Some controllers (JMicron JMB38x) mess up the buffer bits
+	 * for transfers < 4 bytes. As long as it is just one block,
+	 * we can ignore the bits.
+	 */
+	if ((host->quirks & SDHCI_QUIRK_BROKEN_SMALL_PIO) &&
+		(host->data->blocks == 1))
+		mask = ~0;
+
+	while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
+		if (host->data->flags & MMC_DATA_READ)
+			sdhci_read_block_pio(host);
+		else
+			sdhci_write_block_pio(host);
+
+		host->blocks--;
+		if (host->blocks == 0)
+			break;
+	}
+
+	DBG("PIO transfer complete.\n");
+}
+
+static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
+{
+	local_irq_save(*flags);
+	return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
+}
+
+static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags)
+{
+	kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
+	local_irq_restore(*flags);
+}
+
+static int sdhci_adma_table_pre(struct sdhci_host *host,
+	struct mmc_data *data)
+{
+	int direction;
+
+	u8 *desc;
+	u8 *align;
+	dma_addr_t addr;
+	dma_addr_t align_addr;
+	int len, offset;
+
+	struct scatterlist *sg;
+	int i;
+	char *buffer;
+	unsigned long flags;
+
+	/*
+	 * The spec does not specify endianness of descriptor table.
+	 * We currently guess that it is LE.
+	 */
+
+	if (data->flags & MMC_DATA_READ)
+		direction = DMA_FROM_DEVICE;
+	else
+		direction = DMA_TO_DEVICE;
+
+	/*
+	 * The ADMA descriptor table is mapped further down as we
+	 * need to fill it with data first.
+	 */
+
+	host->align_addr = dma_map_single(mmc_dev(host->mmc),
+		host->align_buffer, 128 * 4, direction);
+	if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
+		goto fail;
+	BUG_ON(host->align_addr & 0x3);
+
+	host->sg_count = dma_map_sg(mmc_dev(host->mmc),
+		data->sg, data->sg_len, direction);
+	if (host->sg_count == 0)
+		goto unmap_align;
+
+	desc = host->adma_desc;
+	align = host->align_buffer;
+
+	align_addr = host->align_addr;
+
+	for_each_sg(data->sg, sg, host->sg_count, i) {
+		addr = sg_dma_address(sg);
+		len = sg_dma_len(sg);
+
+		/*
+		 * The SDHCI specification states that ADMA
+		 * addresses must be 32-bit aligned. If they
+		 * aren't, then we use a bounce buffer for
+		 * the (up to three) bytes that screw up the
+		 * alignment.
+		 */
+		offset = (4 - (addr & 0x3)) & 0x3;
+		if (offset) {
+			if (data->flags & MMC_DATA_WRITE) {
+				buffer = sdhci_kmap_atomic(sg, &flags);
+				WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
+				memcpy(align, buffer, offset);
+				sdhci_kunmap_atomic(buffer, &flags);
+			}
+
+			desc[7] = (align_addr >> 24) & 0xff;
+			desc[6] = (align_addr >> 16) & 0xff;
+			desc[5] = (align_addr >> 8) & 0xff;
+			desc[4] = (align_addr >> 0) & 0xff;
+
+			BUG_ON(offset > 65536);
+
+			desc[3] = (offset >> 8) & 0xff;
+			desc[2] = (offset >> 0) & 0xff;
+
+			desc[1] = 0x00;
+			desc[0] = 0x21; /* tran, valid */
+
+			align += 4;
+			align_addr += 4;
+
+			desc += 8;
+
+			addr += offset;
+			len -= offset;
+		}
+
+		desc[7] = (addr >> 24) & 0xff;
+		desc[6] = (addr >> 16) & 0xff;
+		desc[5] = (addr >> 8) & 0xff;
+		desc[4] = (addr >> 0) & 0xff;
+
+		BUG_ON(len > 65536);
+
+		desc[3] = (len >> 8) & 0xff;
+		desc[2] = (len >> 0) & 0xff;
+
+		desc[1] = 0x00;
+		desc[0] = 0x21; /* tran, valid */
+
+		desc += 8;
+
+		/*
+		 * If this triggers then we have a calculation bug
+		 * somewhere. :/
+		 */
+		WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4);
+	}
+
+	/*
+	 * Add a terminating entry.
+	 */
+	desc[7] = 0;
+	desc[6] = 0;
+	desc[5] = 0;
+	desc[4] = 0;
+
+	desc[3] = 0;
+	desc[2] = 0;
+
+	desc[1] = 0x00;
+	desc[0] = 0x03; /* nop, end, valid */
+
+	/*
+	 * Resync align buffer as we might have changed it.
+	 */
+	if (data->flags & MMC_DATA_WRITE) {
+		dma_sync_single_for_device(mmc_dev(host->mmc),
+			host->align_addr, 128 * 4, direction);
+	}
+
+	host->adma_addr = dma_map_single(mmc_dev(host->mmc),
+		host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE);
+	if (dma_mapping_error(mmc_dev(host->mmc), host->adma_addr))
+		goto unmap_entries;
+	BUG_ON(host->adma_addr & 0x3);
+
+	return 0;
+
+unmap_entries:
+	dma_unmap_sg(mmc_dev(host->mmc), data->sg,
+		data->sg_len, direction);
+unmap_align:
+	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
+		128 * 4, direction);
+fail:
+	return -EINVAL;
+}
+
+static void sdhci_adma_table_post(struct sdhci_host *host,
+	struct mmc_data *data)
+{
+	int direction;
+
+	struct scatterlist *sg;
+	int i, size;
+	u8 *align;
+	char *buffer;
+	unsigned long flags;
+
+	if (data->flags & MMC_DATA_READ)
+		direction = DMA_FROM_DEVICE;
+	else
+		direction = DMA_TO_DEVICE;
+
+	dma_unmap_single(mmc_dev(host->mmc), host->adma_addr,
+		(128 * 2 + 1) * 4, DMA_TO_DEVICE);
+
+	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
+		128 * 4, direction);
+
+	if (data->flags & MMC_DATA_READ) {
+		dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg,
+			data->sg_len, direction);
+
+		align = host->align_buffer;
+
+		for_each_sg(data->sg, sg, host->sg_count, i) {
+			if (sg_dma_address(sg) & 0x3) {
+				size = 4 - (sg_dma_address(sg) & 0x3);
+
+				buffer = sdhci_kmap_atomic(sg, &flags);
+				WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
+				memcpy(buffer, align, size);
+				sdhci_kunmap_atomic(buffer, &flags);
+
+				align += 4;
+			}
+		}
+	}
+
+	dma_unmap_sg(mmc_dev(host->mmc), data->sg,
+		data->sg_len, direction);
+}
+
+static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
+{
+	u8 count;
+	unsigned target_timeout, current_timeout;
+
+	/*
+	 * If the host controller provides us with an incorrect timeout
+	 * value, just skip the check and use 0xE.  The hardware may take
+	 * longer to time out, but that's much better than having a too-short
+	 * timeout value.
+	 */
+	if ((host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL))
+		return 0xE;
+
+	/* timeout in us */
+	target_timeout = data->timeout_ns / 1000 +
+		data->timeout_clks / host->clock;
+
+	/*
+	 * Figure out needed cycles.
+	 * We do this in steps in order to fit inside a 32 bit int.
+	 * The first step is the minimum timeout, which will have a
+	 * minimum resolution of 6 bits:
+	 * (1) 2^13*1000 > 2^22,
+	 * (2) host->timeout_clk < 2^16
+	 *     =>
+	 *     (1) / (2) > 2^6
+	 */
+	count = 0;
+	current_timeout = (1 << 13) * 1000 / host->timeout_clk;
+	while (current_timeout < target_timeout) {
+		count++;
+		current_timeout <<= 1;
+		if (count >= 0xF)
+			break;
+	}
+
+	if (count >= 0xF) {
+		printk(KERN_WARNING "%s: Too large timeout requested!\n",
+			mmc_hostname(host->mmc));
+		count = 0xE;
+	}
+
+	return count;
+}
+
+static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
+{
+	u8 count;
+	u8 ctrl;
+	int ret;
+
+	WARN_ON(host->data);
+
+	if (data == NULL)
+		return;
+
+	/* Sanity checks */
+	BUG_ON(data->blksz * data->blocks > 524288);
+	BUG_ON(data->blksz > host->mmc->max_blk_size);
+	BUG_ON(data->blocks > 65535);
+
+	host->data = data;
+	host->data_early = 0;
+
+	count = sdhci_calc_timeout(host, data);
+	writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL);
+
+	if (host->flags & SDHCI_USE_DMA)
+		host->flags |= SDHCI_REQ_USE_DMA;
+
+	/*
+	 * FIXME: This doesn't account for merging when mapping the
+	 * scatterlist.
+	 */
+	if (host->flags & SDHCI_REQ_USE_DMA) {
+		int broken, i;
+		struct scatterlist *sg;
+
+		broken = 0;
+		if (host->flags & SDHCI_USE_ADMA) {
+			if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE)
+				broken = 1;
+		} else {
+			if (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE)
+				broken = 1;
+		}
+
+		if (unlikely(broken)) {
+			for_each_sg(data->sg, sg, data->sg_len, i) {
+				if (sg->length & 0x3) {
+					DBG("Reverting to PIO because of "
+						"transfer size (%d)\n",
+						sg->length);
+					host->flags &= ~SDHCI_REQ_USE_DMA;
+					break;
+				}
+			}
+		}
+	}
+
+	/*
+	 * The assumption here being that alignment is the same after
+	 * translation to device address space.
+	 */
+	if (host->flags & SDHCI_REQ_USE_DMA) {
+		int broken, i;
+		struct scatterlist *sg;
+
+		broken = 0;
+		if (host->flags & SDHCI_USE_ADMA) {
+			/*
+			 * As we use 3 byte chunks to work around
+			 * alignment problems, we need to check this
+			 * quirk.
+			 */
+			if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE)
+				broken = 1;
+		} else {
+			if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR)
+				broken = 1;
+		}
+
+		if (unlikely(broken)) {
+			for_each_sg(data->sg, sg, data->sg_len, i) {
+				if (sg->offset & 0x3) {
+					DBG("Reverting to PIO because of "
+						"bad alignment\n");
+					host->flags &= ~SDHCI_REQ_USE_DMA;
+					break;
+				}
+			}
+		}
+	}
+
+	if (host->flags & SDHCI_REQ_USE_DMA) {
+		if (host->flags & SDHCI_USE_ADMA) {
+			ret = sdhci_adma_table_pre(host, data);
+			if (ret) {
+				/*
+				 * This only happens when someone fed
+				 * us an invalid request.
+				 */
+				WARN_ON(1);
+				host->flags &= ~SDHCI_REQ_USE_DMA;
+			} else {
+				writel(host->adma_addr,
+					host->ioaddr + SDHCI_ADMA_ADDRESS);
+			}
+		} else {
+			int sg_cnt;
+
+			sg_cnt = dma_map_sg(mmc_dev(host->mmc),
+					data->sg, data->sg_len,
+					(data->flags & MMC_DATA_READ) ?
+						DMA_FROM_DEVICE :
+						DMA_TO_DEVICE);
+			if (sg_cnt == 0) {
+				/*
+				 * This only happens when someone fed
+				 * us an invalid request.
+				 */
+				WARN_ON(1);
+				host->flags &= ~SDHCI_REQ_USE_DMA;
+			} else {
+				WARN_ON(sg_cnt != 1);
+				writel(sg_dma_address(data->sg),
+					host->ioaddr + SDHCI_DMA_ADDRESS);
+			}
+		}
+	}
+
+	/*
+	 * Always adjust the DMA selection as some controllers
+	 * (e.g. JMicron) can't do PIO properly when the selection
+	 * is ADMA.
+	 */
+	if (host->version >= SDHCI_SPEC_200) {
+		ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+		ctrl &= ~SDHCI_CTRL_DMA_MASK;
+		if ((host->flags & SDHCI_REQ_USE_DMA) &&
+			(host->flags & SDHCI_USE_ADMA))
+			ctrl |= SDHCI_CTRL_ADMA32;
+		else
+			ctrl |= SDHCI_CTRL_SDMA;
+		writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+	}
+
+	if (!(host->flags & SDHCI_REQ_USE_DMA)) {
+		sg_miter_start(&host->sg_miter,
+			data->sg, data->sg_len, SG_MITER_ATOMIC);
+		host->blocks = data->blocks;
+	}
+
+	/* We do not handle DMA boundaries, so set it to max (512 KiB) */
+	writew(SDHCI_MAKE_BLKSZ(7, data->blksz),
+		host->ioaddr + SDHCI_BLOCK_SIZE);
+	writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT);
+}
+
+static void sdhci_set_transfer_mode(struct sdhci_host *host,
+	struct mmc_data *data)
+{
+	u16 mode;
+
+	if (data == NULL)
+		return;
+
+	WARN_ON(!host->data);
+
+	mode = SDHCI_TRNS_BLK_CNT_EN;
+	if (data->blocks > 1)
+		mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_ACMD12;
+//		mode |= SDHCI_TRNS_MULTI;
+	if (data->flags & MMC_DATA_READ)
+		mode |= SDHCI_TRNS_READ;
+	if (host->flags & SDHCI_REQ_USE_DMA)
+		mode |= SDHCI_TRNS_DMA;
+
+	writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE);
+}
+
+static void sdhci_finish_data(struct sdhci_host *host)
+{
+	struct mmc_data *data;
+
+	BUG_ON(!host->data);
+
+	data = host->data;
+	host->data = NULL;
+
+	if (host->flags & SDHCI_REQ_USE_DMA) {
+		if (host->flags & SDHCI_USE_ADMA)
+			sdhci_adma_table_post(host, data);
+		else {
+			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
+				data->sg_len, (data->flags & MMC_DATA_READ) ?
+					DMA_FROM_DEVICE : DMA_TO_DEVICE);
+		}
+	}
+
+	/*
+	 * The specification states that the block count register must
+	 * be updated, but it does not specify at what point in the
+	 * data flow. That makes the register entirely useless to read
+	 * back so we have to assume that nothing made it to the card
+	 * in the event of an error.
+	 */
+	if (data->error)
+		data->bytes_xfered = 0;
+	else
+		data->bytes_xfered = data->blksz * data->blocks;
+
+	if (data->stop) {
+		/*
+		 * The controller needs a reset of internal state machines
+		 * upon error conditions.
+		 */
+		if (data->error) {
+			sdhci_reset(host, SDHCI_RESET_CMD);
+			sdhci_reset(host, SDHCI_RESET_DATA);
+		}
+
+		sdhci_send_command(host, data->stop);
+	} else
+		tasklet_schedule(&host->finish_tasklet);
+}
+
+static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
+{
+	int flags;
+	u32 mask;
+	unsigned long timeout;
+
+	WARN_ON(host->cmd);
+
+	/* Wait max 10 ms */
+	timeout = 10;
+
+	mask = SDHCI_CMD_INHIBIT;
+	if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY))
+		mask |= SDHCI_DATA_INHIBIT;
+
+	/* We shouldn't wait for data inihibit for stop commands, even
+	   though they might use busy signaling */
+	if (host->mrq->data && (cmd == host->mrq->data->stop))
+		mask &= ~SDHCI_DATA_INHIBIT;
+
+	while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
+		if (timeout == 0) {
+			printk(KERN_ERR "%s: Controller never released "
+				"inhibit bit(s).\n", mmc_hostname(host->mmc));
+			sdhci_dumpregs(host);
+			cmd->error = -EIO;
+			tasklet_schedule(&host->finish_tasklet);
+			return;
+		}
+		timeout--;
+		mdelay(1);
+	}
+
+	mod_timer(&host->timer, jiffies + 10 * HZ);
+
+	host->cmd = cmd;
+
+	sdhci_prepare_data(host, cmd->data);
+
+	writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT);
+
+	sdhci_set_transfer_mode(host, cmd->data);
+
+	if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
+		printk(KERN_ERR "%s: Unsupported response type!\n",
+			mmc_hostname(host->mmc));
+		cmd->error = -EINVAL;
+		tasklet_schedule(&host->finish_tasklet);
+		return;
+	}
+
+	if (!(cmd->flags & MMC_RSP_PRESENT))
+		flags = SDHCI_CMD_RESP_NONE;
+	else if (cmd->flags & MMC_RSP_136)
+		flags = SDHCI_CMD_RESP_LONG;
+	else if (cmd->flags & MMC_RSP_BUSY)
+		flags = SDHCI_CMD_RESP_SHORT_BUSY;
+	else
+		flags = SDHCI_CMD_RESP_SHORT;
+
+	if (cmd->flags & MMC_RSP_CRC)
+		flags |= SDHCI_CMD_CRC;
+	if (cmd->flags & MMC_RSP_OPCODE)
+		flags |= SDHCI_CMD_INDEX;
+	if (cmd->data)
+		flags |= SDHCI_CMD_DATA;
+
+	writew(SDHCI_MAKE_CMD(cmd->opcode, flags),
+		host->ioaddr + SDHCI_COMMAND);
+}
+
+static void sdhci_finish_command(struct sdhci_host *host)
+{
+	int i;
+
+	BUG_ON(host->cmd == NULL);
+
+	if (host->cmd->flags & MMC_RSP_PRESENT) {
+		if (host->cmd->flags & MMC_RSP_136) {
+			/* CRC is stripped so we need to do some shifting. */
+			for (i = 0;i < 4;i++) {
+				host->cmd->resp[i] = readl(host->ioaddr +
+					SDHCI_RESPONSE + (3-i)*4) << 8;
+				if (i != 3)
+					host->cmd->resp[i] |=
+						readb(host->ioaddr +
+						SDHCI_RESPONSE + (3-i)*4-1);
+			}
+		} else {
+			host->cmd->resp[0] = readl(host->ioaddr + SDHCI_RESPONSE);
+		}
+	}
+
+	host->cmd->error = 0;
+
+	if (host->data && host->data_early)
+		sdhci_finish_data(host);
+
+	if (!host->cmd->data)
+		tasklet_schedule(&host->finish_tasklet);
+
+	host->cmd = NULL;
+}
+
+static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+	int div;
+	u16 clk;
+	unsigned long timeout;
+
+	if (clock == host->clock)
+		return;
+
+	writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
+
+	if (clock == 0)
+		goto out;
+
+	for (div = 1;div < 256;div *= 2) {
+		if ((host->max_clk / div) <= clock)
+			break;
+	}
+	div >>= 1;
+	
+	//Issue : For ast2300, ast2400 couldn't set div = 0 means /1 , so set source is ~50Mhz up 
+	
+	clk = div << SDHCI_DIVIDER_SHIFT;
+	clk |= SDHCI_CLOCK_INT_EN;
+	writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+
+	/* Wait max 10 ms */
+	timeout = 10;
+	while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL))
+		& SDHCI_CLOCK_INT_STABLE)) {
+		if (timeout == 0) {
+			printk(KERN_ERR "%s: Internal clock never "
+				"stabilised.\n", mmc_hostname(host->mmc));
+			sdhci_dumpregs(host);
+			return;
+		}
+		timeout--;
+		mdelay(1);
+	}
+
+	clk |= SDHCI_CLOCK_CARD_EN;
+	writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+
+out:
+	host->clock = clock;
+}
+
+static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
+{
+	u8 pwr;
+
+	if (host->power == power)
+		return;
+
+	if (power == (unsigned short)-1) {
+		writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
+		goto out;
+	}
+
+	/*
+	 * Spec says that we should clear the power reg before setting
+	 * a new value. Some controllers don't seem to like this though.
+	 */
+	if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
+		writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
+
+	pwr = SDHCI_POWER_ON;
+
+	switch (1 << power) {
+	case MMC_VDD_165_195:
+		pwr |= SDHCI_POWER_180;
+		break;
+	case MMC_VDD_29_30:
+	case MMC_VDD_30_31:
+		pwr |= SDHCI_POWER_300;
+		break;
+	case MMC_VDD_32_33:
+	case MMC_VDD_33_34:
+		pwr |= SDHCI_POWER_330;
+		break;
+	default:
+		BUG();
+	}
+
+	/*
+	 * At least the Marvell CaFe chip gets confused if we set the voltage
+	 * and set turn on power at the same time, so set the voltage first.
+	 */
+	if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
+		writeb(pwr & ~SDHCI_POWER_ON,
+				host->ioaddr + SDHCI_POWER_CONTROL);
+
+	writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL);
+
+out:
+	host->power = power;
+}
+
+/*****************************************************************************\
+ *                                                                           *
+ * MMC callbacks                                                             *
+ *                                                                           *
+\*****************************************************************************/
+
+static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct sdhci_host *host;
+	unsigned long flags;
+
+	host = mmc_priv(mmc);
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	WARN_ON(host->mrq != NULL);
+
+#ifndef CONFIG_LEDS_CLASS
+	sdhci_activate_led(host);
+#endif
+
+	host->mrq = mrq;
+
+	if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)
+		|| (host->flags & SDHCI_DEVICE_DEAD)) {
+		host->mrq->cmd->error = -ENOMEDIUM;
+		tasklet_schedule(&host->finish_tasklet);
+	} else
+		sdhci_send_command(host, mrq->cmd);
+
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct sdhci_host *host;
+	unsigned long flags;
+	u8 ctrl;
+
+	host = mmc_priv(mmc);
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (host->flags & SDHCI_DEVICE_DEAD)
+		goto out;
+
+	/*
+	 * Reset the chip on each power off.
+	 * Should clear out any weird states.
+	 */
+	if (ios->power_mode == MMC_POWER_OFF) {
+		writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE);
+		sdhci_init(host);
+	}
+
+	sdhci_set_clock(host, ios->clock);
+
+	if (ios->power_mode == MMC_POWER_OFF)
+		sdhci_set_power(host, -1);
+	else
+		sdhci_set_power(host, ios->vdd);
+
+	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+
+	if (ios->bus_width == MMC_BUS_WIDTH_4)
+		ctrl |= SDHCI_CTRL_4BITBUS;
+	else
+		ctrl &= ~SDHCI_CTRL_4BITBUS;
+
+	if (ios->timing == MMC_TIMING_SD_HS)
+		ctrl |= SDHCI_CTRL_HISPD;
+	else
+		ctrl &= ~SDHCI_CTRL_HISPD;
+
+	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+
+	/*
+	 * Some (ENE) controllers go apeshit on some ios operation,
+	 * signalling timeout and CRC errors even on CMD0. Resetting
+	 * it on each ios seems to solve the problem.
+	 */
+	if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
+		sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
+
+out:
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static int sdhci_get_ro(struct mmc_host *mmc)
+{
+	struct sdhci_host *host;
+	unsigned long flags;
+	int present;
+
+	host = mmc_priv(mmc);
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (host->flags & SDHCI_DEVICE_DEAD)
+		present = 0;
+	else
+		present = readl(host->ioaddr + SDHCI_PRESENT_STATE);
+
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	return !(present & SDHCI_WRITE_PROTECT);
+}
+
+static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+	struct sdhci_host *host;
+	unsigned long flags;
+	u32 ier;
+
+	host = mmc_priv(mmc);
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (host->flags & SDHCI_DEVICE_DEAD)
+		goto out;
+
+	ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
+
+	ier &= ~SDHCI_INT_CARD_INT;
+	if (enable)
+		ier |= SDHCI_INT_CARD_INT;
+
+	writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
+	writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
+
+out:
+	mmiowb();
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static const struct mmc_host_ops sdhci_ops = {
+	.request	= sdhci_request,
+	.set_ios	= sdhci_set_ios,
+	.get_ro		= sdhci_get_ro,
+	.enable_sdio_irq = sdhci_enable_sdio_irq,
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * Tasklets                                                                  *
+ *                                                                           *
+\*****************************************************************************/
+
+static void sdhci_tasklet_card(unsigned long param)
+{
+	struct sdhci_host *host;
+	unsigned long flags;
+
+	host = (struct sdhci_host*)param;
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
+		if (host->mrq) {
+			printk(KERN_ERR "%s: Card removed during transfer!\n",
+				mmc_hostname(host->mmc));
+			printk(KERN_ERR "%s: Resetting controller.\n",
+				mmc_hostname(host->mmc));
+
+			sdhci_reset(host, SDHCI_RESET_CMD);
+			sdhci_reset(host, SDHCI_RESET_DATA);
+
+			host->mrq->cmd->error = -ENOMEDIUM;
+			tasklet_schedule(&host->finish_tasklet);
+		}
+	}
+
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	mmc_detect_change(host->mmc, msecs_to_jiffies(200));
+}
+
+static void sdhci_tasklet_finish(unsigned long param)
+{
+	struct sdhci_host *host;
+	unsigned long flags;
+	struct mmc_request *mrq;
+
+	host = (struct sdhci_host*)param;
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	del_timer(&host->timer);
+
+	mrq = host->mrq;
+
+	/*
+	 * The controller needs a reset of internal state machines
+	 * upon error conditions.
+	 */
+	if (!(host->flags & SDHCI_DEVICE_DEAD) &&
+		(mrq->cmd->error ||
+		 (mrq->data && (mrq->data->error ||
+		  (mrq->data->stop && mrq->data->stop->error))) ||
+		   (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) {
+
+		/* Some controllers need this kick or reset won't work here */
+		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) {
+			unsigned int clock;
+
+			/* This is to force an update */
+			clock = host->clock;
+			host->clock = 0;
+			sdhci_set_clock(host, clock);
+		}
+
+		/* Spec says we should do both at the same time, but Ricoh
+		   controllers do not like that. */
+		sdhci_reset(host, SDHCI_RESET_CMD);
+		sdhci_reset(host, SDHCI_RESET_DATA);
+	}
+
+	host->mrq = NULL;
+	host->cmd = NULL;
+	host->data = NULL;
+
+#ifndef CONFIG_LEDS_CLASS
+	sdhci_deactivate_led(host);
+#endif
+
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	mmc_request_done(host->mmc, mrq);
+}
+
+static void sdhci_timeout_timer(unsigned long data)
+{
+	struct sdhci_host *host;
+	unsigned long flags;
+
+	host = (struct sdhci_host*)data;
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (host->mrq) {
+		printk(KERN_ERR "%s: Timeout waiting for hardware "
+			"interrupt.\n", mmc_hostname(host->mmc));
+		sdhci_dumpregs(host);
+
+		if (host->data) {
+			host->data->error = -ETIMEDOUT;
+			sdhci_finish_data(host);
+		} else {
+			if (host->cmd)
+				host->cmd->error = -ETIMEDOUT;
+			else
+				host->mrq->cmd->error = -ETIMEDOUT;
+
+			tasklet_schedule(&host->finish_tasklet);
+		}
+	}
+
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+/*****************************************************************************\
+ *                                                                           *
+ * Interrupt handling                                                        *
+ *                                                                           *
+\*****************************************************************************/
+
+static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
+{
+	BUG_ON(intmask == 0);
+
+	if (!host->cmd) {
+		printk(KERN_ERR "%s: Got command interrupt 0x%08x even "
+			"though no command operation was in progress.\n",
+			mmc_hostname(host->mmc), (unsigned)intmask);
+		sdhci_dumpregs(host);
+		return;
+	}
+
+	if (intmask & SDHCI_INT_TIMEOUT)
+		host->cmd->error = -ETIMEDOUT;
+	else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT |
+			SDHCI_INT_INDEX))
+		host->cmd->error = -EILSEQ;
+
+	if (host->cmd->error) {
+		tasklet_schedule(&host->finish_tasklet);
+		return;
+	}
+
+	/*
+	 * The host can send and interrupt when the busy state has
+	 * ended, allowing us to wait without wasting CPU cycles.
+	 * Unfortunately this is overloaded on the "data complete"
+	 * interrupt, so we need to take some care when handling
+	 * it.
+	 *
+	 * Note: The 1.0 specification is a bit ambiguous about this
+	 *       feature so there might be some problems with older
+	 *       controllers.
+	 */
+	if (host->cmd->flags & MMC_RSP_BUSY) {
+		if (host->cmd->data)
+			DBG("Cannot wait for busy signal when also "
+				"doing a data transfer");
+		else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ))
+			return;
+
+		/* The controller does not support the end-of-busy IRQ,
+		 * fall through and take the SDHCI_INT_RESPONSE */
+	}
+
+	if (intmask & SDHCI_INT_RESPONSE)
+		sdhci_finish_command(host);
+}
+
+static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
+{
+	BUG_ON(intmask == 0);
+
+	if (!host->data) {
+		/*
+		 * The "data complete" interrupt is also used to
+		 * indicate that a busy state has ended. See comment
+		 * above in sdhci_cmd_irq().
+		 */
+		if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) {
+			if (intmask & SDHCI_INT_DATA_END) {
+				sdhci_finish_command(host);
+				return;
+			}
+		}
+
+		printk(KERN_ERR "%s: Got data interrupt 0x%08x even "
+			"though no data operation was in progress.\n",
+			mmc_hostname(host->mmc), (unsigned)intmask);
+		sdhci_dumpregs(host);
+
+		return;
+	}
+
+	if (intmask & SDHCI_INT_DATA_TIMEOUT)
+		host->data->error = -ETIMEDOUT;
+	else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT))
+		host->data->error = -EILSEQ;
+	else if (intmask & SDHCI_INT_ADMA_ERROR)
+		host->data->error = -EIO;
+
+	if (host->data->error)
+		sdhci_finish_data(host);
+	else {
+		if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
+			sdhci_transfer_pio(host);
+
+		/*
+		 * We currently don't do anything fancy with DMA
+		 * boundaries, but as we can't disable the feature
+		 * we need to at least restart the transfer.
+		 */
+		if (intmask & SDHCI_INT_DMA_END)
+			writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS),
+				host->ioaddr + SDHCI_DMA_ADDRESS);
+
+		if (intmask & SDHCI_INT_DATA_END) {
+			if (host->cmd) {
+				/*
+				 * Data managed to finish before the
+				 * command completed. Make sure we do
+				 * things in the proper order.
+				 */
+				host->data_early = 1;
+			} else {
+				sdhci_finish_data(host);
+			}
+		}
+	}
+}
+
+static irqreturn_t sdhci_irq(int irq, void *dev_id)
+{
+	irqreturn_t result;
+	struct sdhci_host* host = dev_id;
+	u32 intmask;
+	int cardint = 0;
+
+	spin_lock(&host->lock);
+
+	intmask = readl(host->ioaddr + SDHCI_INT_STATUS);
+
+	if (!intmask || intmask == 0xffffffff) {
+		result = IRQ_NONE;
+		goto out;
+	}
+
+	DBG("*** %s got interrupt: 0x%08x\n",
+		mmc_hostname(host->mmc), intmask);
+
+	if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
+		writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE),
+			host->ioaddr + SDHCI_INT_STATUS);
+		tasklet_schedule(&host->card_tasklet);
+	}
+
+	intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
+
+	if (intmask & SDHCI_INT_CMD_MASK) {
+		writel(intmask & SDHCI_INT_CMD_MASK,
+			host->ioaddr + SDHCI_INT_STATUS);
+		sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
+	}
+
+	if (intmask & SDHCI_INT_DATA_MASK) {
+		writel(intmask & SDHCI_INT_DATA_MASK,
+			host->ioaddr + SDHCI_INT_STATUS);
+		sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
+	}
+
+	intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
+
+	intmask &= ~SDHCI_INT_ERROR;
+
+	if (intmask & SDHCI_INT_BUS_POWER) {
+		printk(KERN_ERR "%s: Card is consuming too much power!\n",
+			mmc_hostname(host->mmc));
+		writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS);
+	}
+
+	intmask &= ~SDHCI_INT_BUS_POWER;
+
+	if (intmask & SDHCI_INT_CARD_INT)
+		cardint = 1;
+
+	intmask &= ~SDHCI_INT_CARD_INT;
+
+	if (intmask) {
+		printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
+			mmc_hostname(host->mmc), intmask);
+		sdhci_dumpregs(host);
+
+		writel(intmask, host->ioaddr + SDHCI_INT_STATUS);
+	}
+
+	result = IRQ_HANDLED;
+
+	mmiowb();
+out:
+	spin_unlock(&host->lock);
+
+	/*
+	 * We have to delay this as it calls back into the driver.
+	 */
+	if (cardint)
+		mmc_signal_sdio_irq(host->mmc);
+
+	return result;
+}
+
+/*****************************************************************************\
+ *                                                                           *
+ * Suspend/resume                                                            *
+ *                                                                           *
+\*****************************************************************************/
+
+#ifdef CONFIG_PM
+
+int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
+{
+	int ret;
+
+	ret = mmc_suspend_host(host->mmc, state);
+	if (ret)
+		return ret;
+
+	free_irq(host->irq, host);
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(sdhci_suspend_host);
+
+int sdhci_resume_host(struct sdhci_host *host)
+{
+	int ret;
+
+	if (host->flags & SDHCI_USE_DMA) {
+/*
+		if (host->ops->enable_dma)
+			host->ops->enable_dma(host);
+*/
+	}
+
+	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
+			  mmc_hostname(host->mmc), host);
+	if (ret)
+		return ret;
+
+	sdhci_init(host);
+	mmiowb();
+
+	ret = mmc_resume_host(host->mmc);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(sdhci_resume_host);
+
+#endif /* CONFIG_PM */
+
+/*****************************************************************************\
+ *                                                                           *
+ * Device allocation/registration                                            *
+ *                                                                           *
+\*****************************************************************************/
+
+struct sdhci_host *sdhci_alloc_host(struct device *dev,
+	size_t priv_size)
+{
+	struct mmc_host *mmc;
+	struct sdhci_host *host;
+
+	WARN_ON(dev == NULL);
+
+	mmc = mmc_alloc_host(sizeof(struct sdhci_host) + priv_size, dev);
+	if (!mmc)
+		return ERR_PTR(-ENOMEM);
+
+	host = mmc_priv(mmc);
+	host->mmc = mmc;
+
+	return host;
+}
+
+//EXPORT_SYMBOL_GPL(sdhci_alloc_host);
+
+int sdhci_add_host(struct sdhci_host *host)
+{
+	struct mmc_host *mmc;
+	unsigned int caps, temp;
+	int ret;
+
+	WARN_ON(host == NULL);
+	if (host == NULL)
+		return -EINVAL;
+#if 0
+	//TODO
+//Both ports's capabilities are 0, software needs to reset SDIO
+#define	SDIO000				0x1e740000
+#define	SDIO004				0x1e740004
+	
+#define	SDIO_ALL_SOFTWARE_RESET		0x01
+
+	if ((*(unsigned int*)(IO_ADDRESS(0x1E740140)) == 0) && (*(unsigned int*)(IO_ADDRESS(0x1E740240)) == 0)) {
+		temp = *(unsigned int*)(IO_ADDRESS(SDIO000));
+		*(unsigned int*)(IO_ADDRESS(SDIO000)) = temp | SDIO_ALL_SOFTWARE_RESET;
+		barrier();
+		do {
+			temp = (*(unsigned int*)(IO_ADDRESS(SDIO000)) & SDIO_ALL_SOFTWARE_RESET);
+		} while (temp == SDIO_ALL_SOFTWARE_RESET);
+	}
+	//Card detect debounce timing 
+	*(unsigned int*)(IO_ADDRESS(SDIO004)) = 0x1000;
+#endif	
+	///////////////////////////////////////////////////////////////////
+	
+	mmc = host->mmc;
+
+	if (debug_quirks)
+		host->quirks = debug_quirks;
+
+	sdhci_reset(host, SDHCI_RESET_ALL);
+
+	host->version = readw(host->ioaddr + SDHCI_HOST_VERSION);
+	host->version = (host->version & SDHCI_SPEC_VER_MASK)
+				>> SDHCI_SPEC_VER_SHIFT;
+	if (host->version > SDHCI_SPEC_200) {
+		printk(KERN_ERR "%s: Unknown controller version (%d). "
+			"You may experience problems.\n", mmc_hostname(mmc),
+			host->version);
+	}
+
+	caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
+
+	//Ryan Add for timeout 
+	host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+//	host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
+
+	if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
+		host->flags |= SDHCI_USE_DMA;
+	else if (!(caps & SDHCI_CAN_DO_DMA))
+		DBG("Controller doesn't have DMA capability\n");
+	else
+		host->flags |= SDHCI_USE_DMA;
+
+	if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
+		(host->flags & SDHCI_USE_DMA)) {
+		DBG("Disabling DMA as it is marked broken\n");
+		host->flags &= ~SDHCI_USE_DMA;
+	}
+
+	if (host->flags & SDHCI_USE_DMA) {
+		if ((host->version >= SDHCI_SPEC_200) &&
+				(caps & SDHCI_CAN_DO_ADMA2))
+			host->flags |= SDHCI_USE_ADMA;
+	}
+
+	if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
+		(host->flags & SDHCI_USE_ADMA)) {
+		DBG("Disabling ADMA as it is marked broken\n");
+		host->flags &= ~SDHCI_USE_ADMA;
+	}
+
+	if (host->flags & SDHCI_USE_DMA) {
+/*
+		if (host->ops->enable_dma) {
+			if (host->ops->enable_dma(host)) {
+				printk(KERN_WARNING "%s: No suitable DMA "
+					"available. Falling back to PIO.\n",
+					mmc_hostname(mmc));
+				host->flags &= ~(SDHCI_USE_DMA | SDHCI_USE_ADMA);
+			}
+		}
+*/
+	}
+
+	if (host->flags & SDHCI_USE_ADMA) {
+		/*
+		 * We need to allocate descriptors for all sg entries
+		 * (128) and potentially one alignment transfer for
+		 * each of those entries.
+		 */
+		host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL);
+		host->align_buffer = kmalloc(128 * 4, GFP_KERNEL);
+		if (!host->adma_desc || !host->align_buffer) {
+			kfree(host->adma_desc);
+			kfree(host->align_buffer);
+			printk(KERN_WARNING "%s: Unable to allocate ADMA "
+				"buffers. Falling back to standard DMA.\n",
+				mmc_hostname(mmc));
+			host->flags &= ~SDHCI_USE_ADMA;
+		}
+	}
+
+	/*
+	 * If we use DMA, then it's up to the caller to set the DMA
+	 * mask, but PIO does not need the hw shim so we set a new
+	 * mask here in that case.
+	 */
+	if (!(host->flags & SDHCI_USE_DMA)) {
+		host->dma_mask = DMA_BIT_MASK(64);
+		mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
+	}
+
+//	host->max_clk =
+//		(caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
+
+	host->max_clk = ast_sdhc_info->sd_clock_src_get()/1000000;
+//	printk("host->max_clk = %d Mhz\n",host->max_clk);
+	
+	if (host->max_clk == 0) {
+		printk(KERN_ERR "%s: Hardware doesn't specify base clock "
+			"frequency.\n", mmc_hostname(mmc));
+		return -ENODEV;
+	}
+	host->max_clk *= 1000000;
+
+	//Ryan modify for calc timeout issue
+	host->timeout_clk =  ast_sdhc_info->sd_clock_src_get()/1000000;
+//		(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
+	if (host->timeout_clk == 0) {
+		printk(KERN_ERR "%s: Hardware doesn't specify timeout clock "
+			"frequency.\n", mmc_hostname(mmc));
+		return -ENODEV;
+	}
+	if (caps & SDHCI_TIMEOUT_CLK_UNIT)
+		host->timeout_clk *= 1000;
+
+	/*
+	 * Set host parameters.
+	 */
+	mmc->ops = &sdhci_ops;
+	mmc->f_min = host->max_clk / 256;
+	mmc->f_max = host->max_clk;
+	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+
+	if ((caps & SDHCI_CAN_DO_HISPD) ||
+		(host->quirks & SDHCI_QUIRK_FORCE_HIGHSPEED))
+		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
+
+	mmc->caps |= MMC_CAP_MMC_HIGHSPEED;
+
+	mmc->ocr_avail = 0;
+	if (caps & SDHCI_CAN_VDD_330)
+		mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
+	if (caps & SDHCI_CAN_VDD_300)
+		mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31;
+	if (caps & SDHCI_CAN_VDD_180)
+		mmc->ocr_avail |= MMC_VDD_165_195;
+
+	if (mmc->ocr_avail == 0) {
+		printk(KERN_ERR "%s: Hardware doesn't report any "
+			"support voltages.\n", mmc_hostname(mmc));
+		return -ENODEV;
+	}
+
+	spin_lock_init(&host->lock);
+
+	/*
+	 * Maximum number of segments. Depends on if the hardware
+	 * can do scatter/gather or not.
+	 */
+	if (host->flags & SDHCI_USE_ADMA)
+		mmc->max_hw_segs = 128;
+	else if (host->flags & SDHCI_USE_DMA)
+		mmc->max_hw_segs = 1;
+	else /* PIO */
+		mmc->max_hw_segs = 128;
+	mmc->max_phys_segs = 128;
+
+	/*
+	 * Maximum number of sectors in one transfer. Limited by DMA boundary
+	 * size (512KiB).
+	 */
+	mmc->max_req_size = 524288;
+
+	/*
+	 * Maximum segment size. Could be one segment with the maximum number
+	 * of bytes. When doing hardware scatter/gather, each entry cannot
+	 * be larger than 64 KiB though.
+	 */
+	if (host->flags & SDHCI_USE_ADMA)
+		mmc->max_seg_size = 65536;
+	else
+		mmc->max_seg_size = mmc->max_req_size;
+
+	/*
+	 * Maximum block size. This varies from controller to controller and
+	 * is specified in the capabilities register.
+	 */
+	mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
+	if (mmc->max_blk_size >= 3) {
+		printk(KERN_WARNING "%s: Invalid maximum block size, "
+			"assuming 512 bytes\n", mmc_hostname(mmc));
+		mmc->max_blk_size = 512;
+	} else
+		mmc->max_blk_size = 512 << mmc->max_blk_size;
+
+	/*
+	 * Maximum block count.
+	 */
+	mmc->max_blk_count = 65535;
+
+	/*
+	 * Init tasklets.
+	 */
+	tasklet_init(&host->card_tasklet,
+		sdhci_tasklet_card, (unsigned long)host);
+	tasklet_init(&host->finish_tasklet,
+		sdhci_tasklet_finish, (unsigned long)host);
+
+	setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host);
+
+	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
+		mmc_hostname(mmc), host);
+	if (ret)
+		goto untasklet;
+
+	sdhci_init(host);
+
+#ifdef CONFIG_MMC_DEBUG
+	sdhci_dumpregs(host);
+#endif
+
+#ifdef CONFIG_LEDS_CLASS
+	snprintf(host->led_name, sizeof(host->led_name),
+		"%s::", mmc_hostname(mmc));
+	host->led.name = host->led_name;
+	host->led.brightness = LED_OFF;
+	host->led.default_trigger = mmc_hostname(mmc);
+	host->led.brightness_set = sdhci_led_control;
+
+	ret = led_classdev_register(mmc_dev(mmc), &host->led);
+	if (ret)
+		goto reset;
+#endif
+
+	mmiowb();
+
+	mmc_add_host(mmc);
+
+	printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n",
+		mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
+		(host->flags & SDHCI_USE_ADMA)?"A":"",
+		(host->flags & SDHCI_USE_DMA)?"DMA":"PIO");
+
+	return 0;
+
+#ifdef CONFIG_LEDS_CLASS
+reset:
+	sdhci_reset(host, SDHCI_RESET_ALL);
+	free_irq(host->irq, host);
+#endif
+untasklet:
+	tasklet_kill(&host->card_tasklet);
+	tasklet_kill(&host->finish_tasklet);
+
+	return ret;
+}
+
+//EXPORT_SYMBOL_GPL(sdhci_add_host);
+
+static int sdhci_probe(struct platform_device *pdev)
+{
+	struct sdhci_host *host;
+	struct resource *res;
+	int ret;
+	ast_sdhc_info = pdev->dev.platform_data;
+
+	host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_host));
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (NULL == res) {
+		dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
+		ret = -ENOENT;
+		return ret;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res), res->name)) {
+        dev_err(&pdev->dev, "cannot reserved region\n");
+        ret = -ENXIO;
+		return ret;
+	}
+
+	host->ioaddr = ioremap(res->start, resource_size(res));
+	if (!host->ioaddr) {
+		ret = -EIO;
+		return ret;
+	}
+
+	host->hw_name = res->name;
+	host->irq = platform_get_irq(pdev, 0);
+	if (host->irq < 0) {
+		dev_err(&pdev->dev, "no irq specified\n");
+		ret = -ENOENT;
+		return ret;
+	}
+
+	ret = sdhci_add_host(host);
+
+	return ret;
+}
+
+void sdhci_remove_host(struct sdhci_host *host, int dead)
+{
+	unsigned long flags;
+
+	if (dead) {
+		spin_lock_irqsave(&host->lock, flags);
+
+		host->flags |= SDHCI_DEVICE_DEAD;
+
+		if (host->mrq) {
+			printk(KERN_ERR "%s: Controller removed during "
+				" transfer!\n", mmc_hostname(host->mmc));
+
+			host->mrq->cmd->error = -ENOMEDIUM;
+			tasklet_schedule(&host->finish_tasklet);
+		}
+
+		spin_unlock_irqrestore(&host->lock, flags);
+	}
+
+	mmc_remove_host(host->mmc);
+
+#ifdef CONFIG_LEDS_CLASS
+	led_classdev_unregister(&host->led);
+#endif
+
+	if (!dead)
+		sdhci_reset(host, SDHCI_RESET_ALL);
+
+	free_irq(host->irq, host);
+
+	del_timer_sync(&host->timer);
+
+	tasklet_kill(&host->card_tasklet);
+	tasklet_kill(&host->finish_tasklet);
+
+	kfree(host->adma_desc);
+	kfree(host->align_buffer);
+
+	host->adma_desc = NULL;
+	host->align_buffer = NULL;
+}
+
+EXPORT_SYMBOL_GPL(sdhci_remove_host);
+
+void sdhci_free_host(struct sdhci_host *host)
+{
+	mmc_free_host(host->mmc);
+}
+
+EXPORT_SYMBOL_GPL(sdhci_free_host);
+
+/*****************************************************************************\
+ *                                                                           *
+ * Driver init/exit                                                          *
+ *                                                                           *
+\*****************************************************************************/
+
+static struct platform_driver ast_sdhci_driver = {
+	.driver.name	= "ast_sdhci",
+	.driver.owner	= THIS_MODULE,
+	.probe		= sdhci_probe,
+	.remove		= __exit_p(sdhci_remove_host),
+#ifdef CONFIG_PM	
+	.resume		= sdhci_resume_host,
+	.suspend	= sdhci_suspend_host,
+#endif
+};
+
+static int __init ast_sdhci_drv_init(void)
+{
+	return platform_driver_register(&ast_sdhci_driver);
+}
+
+static void __exit ast_sdhci_drv_exit(void)
+{
+	platform_driver_unregister(&ast_sdhci_driver);
+}
+
+module_init(ast_sdhci_drv_init);
+module_exit(ast_sdhci_drv_exit);
+
+module_param(debug_quirks, uint, 0444);
+
+MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx> & River Huang");
+MODULE_DESCRIPTION("ASPEED Secure Digital Host Controller Interface core driver");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM_DESC(debug_quirks, "Force certain quirks.");
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 6659b22..45cb05a 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -503,6 +503,15 @@ static struct flash_info __devinitdata m25p_data [] = {
 	{ "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, },
 	{ "at26df321",  0x1f4701, 0, 64 * 1024, 64, SECT_4K, },
 
+		  /* Macronix */
+	{ "mx25l4005a",	0xc22013, 0, 64 * 1024,   8, SECT_4K },
+	{ "mx25l3205d",	0xc22016, 0, 64 * 1024,  64, 0 },
+	{ "mx25l6405d",	0xc22017, 0, 64 * 1024, 128, 0 },
+	{ "mx25l12805d", 0xc22018, 0, 64 * 1024, 256, 0 },
+
+	{ "mx25l12855e", 0xc22618, 0, 64 * 1024, 256, 0 },
+	{ "mx25l25635e", 0xc22019, 0, 64 * 1024, 512, 0 },
+
 	/* Spansion -- single (large) sector size only, at least
 	 * for the chips listed here (without boot sectors).
 	 */
@@ -511,7 +520,7 @@ static struct flash_info __devinitdata m25p_data [] = {
 	{ "s25sl016a", 0x010214, 0, 64 * 1024, 32, },
 	{ "s25sl032a", 0x010215, 0, 64 * 1024, 64, },
 	{ "s25sl064a", 0x010216, 0, 64 * 1024, 128, },
-        { "s25sl12800", 0x012018, 0x0300, 256 * 1024, 64, },
+    { "s25sl12800", 0x012018, 0x0300, 256 * 1024, 64, },
 	{ "s25sl12801", 0x012018, 0x0301, 64 * 1024, 256, },
 
 	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 5ea1693..bafa60c 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -351,6 +351,10 @@ config MTD_ARM_INTEGRATOR
 	tristate "CFI Flash device mapped on ARM Integrator/P720T"
 	depends on ARM && MTD_CFI
 
+config MTD_AST
+        tristate "CFI Flash device mapped on ASPEED"
+        depends on ARCH_ASPEED && MTD_CFI
+
 config MTD_CDB89712
 	tristate "Cirrus CDB89712 evaluation board mappings"
 	depends on MTD_CFI && ARCH_CDB89712
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 6d9ba35..3d8b1f2 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -9,6 +9,7 @@ endif
 # Chip mappings
 obj-$(CONFIG_MTD_CDB89712)	+= cdb89712.o
 obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
+obj-$(CONFIG_MTD_AST)		+= ast-nor.o
 obj-$(CONFIG_MTD_CFI_FLAGADM)	+= cfi_flagadm.o
 obj-$(CONFIG_MTD_DC21285)	+= dc21285.o
 obj-$(CONFIG_MTD_DILNETPC)	+= dilnetpc.o
diff --git a/drivers/mtd/maps/ast-nor.c b/drivers/mtd/maps/ast-nor.c
new file mode 100644
index 0000000..7cc4741
--- /dev/null
+++ b/drivers/mtd/maps/ast-nor.c
@@ -0,0 +1,221 @@
+/*======================================================================
+
+    drivers/mtd/maps/ast-nor.c: ASPEED flash map driver
+
+    Copyright (C) 2012-2020  ASPEED Technology 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
+
+   This is access code for flashes using ARM's flash partitioning
+   standards.
+
+*  History:
+*	 2012.10.11: Initial version [Ryan Chen]
+
+======================================================================*/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/flash.h>
+#include <mach/hardware.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <mach/platform.h>
+
+#define PFX "ast-flash: "
+
+struct ast_flash_info {
+	struct mtd_info		*mtd;
+	struct map_info		map;
+	struct resource		*res;
+	struct mtd_partition	*partitions;
+//	struct flash_platform_data *plat;
+};
+
+static int ast_flash_probe(struct platform_device *pdev)
+{
+	struct ast_flash_info *info;
+	struct flash_platform_data *pdata = pdev->dev.platform_data;
+	struct resource *res = NULL;
+
+	int ret;
+	static int no_partitions;
+	info = kzalloc(sizeof(struct ast_flash_info), GFP_KERNEL);
+	if (info == NULL) {
+		printk(KERN_ERR PFX "no memory for flash info\n");
+		return -ENOMEM;
+	}
+	
+	/* request register map resource & check */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+        if (!res) {
+                dev_err(&pdev->dev, "register resources unusable\n");
+                ret = -ENXIO;
+                goto free_dev;
+        }
+
+	if (!request_mem_region(res->start, res->end - res->start + 1, pdev->name)) {
+		ret = -EBUSY;
+		goto free_something_1;
+	}
+
+	info->map.virt = ioremap(res->start, (res->end - res->start) + 1);
+	if (!info->map.virt) {
+		dev_err(&pdev->dev, "cannot map ast_flash_info registers\n");
+		ret = -ENOMEM;
+		goto release_mem;
+	}	
+	info->map.phys = res->start;
+	info->map.size = res->end - res->start + 1;
+	info->map.name = (char *) pdata->map_name;	
+#ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
+		info->map.bankwidth = 1;
+#endif
+#ifdef CONFIG_MTD_MAP_BANK_WIDTH_2
+		info->map.bankwidth = 2;
+#endif	
+	platform_set_drvdata(pdev, info);
+
+	printk("%s %x, %x, %s \n",__FUNCTION__,res->start,res->end,pdev->dev.bus_id);
+
+	printk("%s: area %08lx, size %lx\n", __FUNCTION__, info->map.phys, info->map.size);
+
+	printk("%s: virt at %08x, res->start %x \n", __FUNCTION__, (int)info->map.virt,res->start);
+
+	info->partitions = pdata->parts;
+
+	simple_map_init(&info->map);
+
+	/* probe for the device(s) */
+
+	info->mtd = do_map_probe(pdata->map_name, &info->map);
+	if (!info->mtd) {
+		ret = -EIO;
+		goto reset_drvdata;
+	}
+
+	/* mark ourselves as the owner */
+	info->mtd->owner = THIS_MODULE;
+
+	no_partitions = pdata->nr_parts;//ARRAY_SIZE(nor_partitions);
+	ret = add_mtd_partitions(info->mtd, info->partitions, no_partitions);
+	if (ret){
+		printk(KERN_ERR PFX "cannot add/parse partitions\n");
+		goto free_something_2;
+	}
+
+	return 0;
+
+	/* fall through to exit error */
+
+free_something_2:
+	del_mtd_partitions(info->mtd);
+	map_destroy(info->mtd);
+reset_drvdata:
+        //kfree(info->partitions);
+	platform_set_drvdata(pdev, NULL);
+//unmap_regs:
+	iounmap(info->map.virt);
+release_mem:
+    release_mem_region(res->start, (res->end - res->start) + 1);
+free_something_1:
+
+free_dev:
+	kfree(info);
+
+	return ret;
+}
+
+static int ast_flash_remove(struct platform_device *pdev)
+{
+        struct ast_flash_info *info = platform_get_drvdata(pdev);
+        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+		if(info) {
+			if (info->mtd) {
+		        del_mtd_partitions(info->mtd);
+		        map_destroy(info->mtd);
+			}
+	        platform_set_drvdata(pdev, NULL);
+	        iounmap(info->map.virt);
+
+	        release_mem_region(res->start, (res->end - res->start) + 1);
+	        kfree(info);
+		}
+		
+        return 0;
+}
+
+
+#ifdef CONFIG_PM
+static int
+ast_flash_suspend(struct platform_device *pdev, pm_message_t msg)
+{
+        pr_debug("ast_flash_suspend\n");
+
+        return 0;
+}
+
+static int
+ast_flash_resume(struct platform_device *pdev)
+{
+        pr_debug("ast_flash_resume\n");
+
+        return 0;
+}
+#else
+#define ast_flash_suspend NULL
+#define ast_flash_resume NULL
+#endif
+
+static struct platform_driver ast_flash_driver = {
+        .probe          = ast_flash_probe,
+        .remove         = ast_flash_remove,
+        .suspend 		= ast_flash_suspend,
+        .resume 		= ast_flash_resume,
+        .driver         = {
+                .name   = "ast-nor",
+                .owner  = THIS_MODULE,
+        },
+};
+
+static int __init ast_flash_init(void)
+{
+        printk("ASPEED NOR-Flash Driver, (c) 2012 Aspeed Tech \n");
+        return platform_driver_register(&ast_flash_driver);
+}
+
+static void __exit ast_flash_exit(void)
+{
+        platform_driver_unregister(&ast_flash_driver);
+}
+
+module_init(ast_flash_init);
+module_exit(ast_flash_exit);
+
+MODULE_AUTHOR("Ryan Chen");
+MODULE_DESCRIPTION("ASPEED AST CFI map driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:astflash");
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 1c2e945..e1ab76b 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -56,6 +56,12 @@ config MTD_NAND_H1900
 	help
 	  This enables the driver for the iPAQ h1900 flash.
 
+config MTD_NAND_AST
+	tristate "AST NAND flash"
+	depends on MTD_NAND && ARCH_ASPEED && MTD_PARTITIONS
+	help
+	  This enables the driver for the ASPEED NAND flash.
+
 config MTD_NAND_GPIO
 	tristate "GPIO NAND Flash driver"
 	depends on GENERIC_GPIO && ARM
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index b661586..129dfd3 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -36,5 +36,6 @@ obj-$(CONFIG_MTD_NAND_FSL_ELBC)		+= fsl_elbc_nand.o
 obj-$(CONFIG_MTD_NAND_FSL_UPM)		+= fsl_upm.o
 obj-$(CONFIG_MTD_NAND_SH_FLCTL)		+= sh_flctl.o
 obj-$(CONFIG_MTD_NAND_MXC)		+= mxc_nand.o
+obj-$(CONFIG_MTD_NAND_AST)		+= ast_nand.o
 
 nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/ast_nand.c b/drivers/mtd/nand/ast_nand.c
new file mode 100755
index 0000000..240a832
--- /dev/null
+++ b/drivers/mtd/nand/ast_nand.c
@@ -0,0 +1,197 @@
+/********************************************************************************
+* File Name     :  drivers/mtd/nand/aspeed_nand.c
+* Author        : Ryan Chen
+* Description   : ASPEED NAND driver
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+*  Overview:
+*	This is a device driver for the NAND flash device found on the
+*	ASPEED board which utilizes the Samsung K9F2808 part. This is
+*	a 128Mibit (16MiB x 8 bits) NAND flash device.
+
+*   History      :
+*	1. 2012/10/20 Ryan Chen create this file
+*
+********************************************************************************/
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+struct ast_nand_data {
+	struct nand_chip	chip;
+	struct mtd_info		mtd;
+	void __iomem		*io_base;
+#ifdef CONFIG_MTD_PARTITIONS
+	int			nr_parts;
+	struct mtd_partition	*parts;
+#endif
+};
+
+static struct nand_ecclayout aspeed_nand_hw_eccoob = {
+	.eccbytes = 24,
+	.eccpos = {40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63},
+};
+
+/* hardware specific access to control-lines  */
+static void 
+ast_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	if (cmd != NAND_CMD_NONE) {
+		//writeb(cmd, chip->IO_ADDR_W + ((ctrl & 0x6) << 11));
+		//user mode cmd addr[13:12]
+		if(ctrl & NAND_CLE)
+			writeb(cmd, chip->IO_ADDR_W + (0x1 << 12));
+		else if (ctrl & NAND_ALE)
+			writeb(cmd, chip->IO_ADDR_W + (0x2 << 12));
+		else 
+			writeb(cmd, chip->IO_ADDR_W + (1 << 12));
+	}
+}
+
+/*
+ * Main initialization routine
+ */
+static int __init 
+ast_nand_probe(struct platform_device *pdev)
+{
+	struct ast_nand_data *data;
+	struct platform_nand_data *pdata = pdev->dev.platform_data;
+	int res = 0;
+
+	/* Allocate memory for the device structure (and zero it) */
+	data = kzalloc(sizeof(struct ast_nand_data), GFP_KERNEL);
+	if (!data) {
+			dev_err(&pdev->dev, "failed to allocate device structure.\n");
+			return -ENOMEM;
+	}
+
+	data->io_base = ioremap(pdev->resource[0].start,
+							pdev->resource[0].end - pdev->resource[0].start );
+	if (data->io_base == NULL) {
+			dev_err(&pdev->dev, "ioremap failed\n");
+			kfree(data);
+			return -EIO;
+	}
+
+	data->chip.priv = &data;
+	data->mtd.priv = &data->chip;
+	data->mtd.owner = THIS_MODULE;
+	data->mtd.name = pdev->dev.bus_id;
+	
+	data->chip.IO_ADDR_R = data->io_base;
+	data->chip.IO_ADDR_W = data->io_base;
+	data->chip.cmd_ctrl = ast_hwcontrol;
+	data->chip.dev_ready = pdata->ctrl.dev_ready;
+	data->chip.select_chip = pdata->ctrl.select_chip;
+	data->chip.chip_delay = pdata->chip.chip_delay;
+	data->chip.options |= pdata->chip.options;
+	
+	data->chip.ecc.hwctl = pdata->ctrl.hwcontrol;
+	data->chip.ecc.calculate = pdata->ctrl.calculate;
+	data->chip.ecc.correct = pdata->ctrl.correct;
+//	data->chip.ecc.layout = pdata->chip.ecclayout;
+	data->chip.ecc.layout = &aspeed_nand_hw_eccoob;
+	
+	data->chip.ecc.bytes = 6;
+	data->chip.ecc.size = 512;	
+	data->chip.ecc.mode = NAND_ECC_HW; //NAND_ECC_SOFT;
+
+	platform_set_drvdata(pdev, data);
+
+	 /* Scan to find existance of the device */
+	 if (nand_scan(&data->mtd, 1)) {
+			 res = -ENXIO;
+			 goto out;
+	 }
+#ifdef CONFIG_MTD_PARTITIONS
+	if (pdata->chip.part_probe_types) {
+			res = parse_mtd_partitions(&data->mtd,
+									pdata->chip.part_probe_types,
+									&data->parts, 0);
+			if (res > 0) {
+					add_mtd_partitions(&data->mtd, data->parts, res);
+					return 0;
+			}
+	}
+	if (pdata->chip.partitions) {
+			data->parts = pdata->chip.partitions;
+			res = add_mtd_partitions(&data->mtd, data->parts,
+					pdata->chip.nr_partitions);
+	} else
+#endif
+	res = add_mtd_device(&data->mtd);
+
+	if (!res)
+			return res;
+
+	nand_release(&data->mtd);
+out:
+	platform_set_drvdata(pdev, NULL);
+	iounmap(data->io_base);
+	kfree(data);
+
+	return res;
+
+}
+
+static int __devexit ast_nand_remove(struct platform_device *pdev)
+{
+	struct ast_nand_data *data = platform_get_drvdata(pdev);
+#ifdef CONFIG_MTD_PARTITIONS
+	struct platform_nand_data *pdata = pdev->dev.platform_data;
+#endif
+
+	nand_release(&data->mtd);
+#ifdef CONFIG_MTD_PARTITIONS
+	if (data->parts && data->parts != pdata->chip.partitions)
+		kfree(data->parts);
+#endif
+	iounmap(data->io_base);
+	kfree(data);
+
+	return 0;
+}
+
+static struct platform_driver ast_nand_driver = {
+        .probe          = ast_nand_probe,
+        .remove         = ast_nand_remove,
+        .driver         = {
+                .name   = "ast-nand",
+                .owner  = THIS_MODULE,
+        },
+};
+
+static int __init ast_nand_init(void)
+{
+        return platform_driver_register(&ast_nand_driver);
+}
+
+static void __exit ast_nand_exit(void)
+{
+        platform_driver_unregister(&ast_nand_driver);
+}
+
+module_init(ast_nand_init);
+module_exit(ast_nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ryan Chen");
+MODULE_DESCRIPTION("NAND flash driver for ASPEED");
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 231eeaf..e017c36 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1889,6 +1889,9 @@ menuconfig NETDEV_1000
 
 if NETDEV_1000
 
+config ASPEEDMAC
+        tristate "ASPEED MAC support"
+
 config ACENIC
 	tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
 	depends on PCI
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 017383a..3c04c0b 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
 obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
 obj-$(CONFIG_RIONET) += rionet.o
 obj-$(CONFIG_SH_ETH) += sh_eth.o
+obj-$(CONFIG_ASPEEDMAC) += ftgmac100_26.o
 
 #
 # end link order section
diff --git a/drivers/net/ftgmac100_26.c b/drivers/net/ftgmac100_26.c
new file mode 100644
index 0000000..8575293
--- /dev/null
+++ b/drivers/net/ftgmac100_26.c
@@ -0,0 +1,1883 @@
+/********************************************************************************
+* File Name     : ftgmac100_26.c
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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 
+********************************************************************************/
+//-----------------------------------------------------------------------------
+//  "ASPEED MAC Driver, (Linux Kernel 2.6.15.7) 10/02/07 - by ASPEED\n"
+// Further improvements:
+//
+//   -- Assume MAC1 has a PHY chip.  Read the chip type and handle Marvell
+//      or Broadcom, else don't touch PHY chip (if present).
+//
+//   -- If MAC2 is on, check if U-Boot enabled the MII2DC+MII2DIO pins.
+//      If yes, handle Marvell or Broadcom PHY.  If no, assume sideband RMII
+//      interface with no PHY chip.
+// 1.12/27/07 - by river@aspeed
+//   Workaround for the gigabit hash function
+// 2.12/27/07 - by river@aspeed
+//   Synchronize the EDORR bit with document, D[30], D[15] both are EDORR
+// 3.12/31/07 - by river@aspeed
+//   Add aspeed_i2c_init and aspeed_i2c_read function for DHCP
+// 4.04/10/2008 - by river@aspeed
+//   Synchronize the EDOTR bit with document, D[30] is EDOTR
+// 5.04/10/2008 - by river@aspeed
+//   Remove the workaround for multicast hash function in A2 chip
+// SDK 0.19
+// 6.05/15/2008 - by river@aspeed
+//   Fix bug of free sk_buff in wrong routine
+// 7.05/16/2008 - by river@aspeed
+//   Fix bug of skb_over_panic()
+// 8.05/22/2008 - by river@aspeed
+//   Support NCSI Feature
+// SDK 0.20
+// 9.07/02/2008 - by river@aspeed
+//   Fix TX will drop packet bug
+// SDK 0.21
+//10.08/06/2008 - by river@aspeed
+//   Add the netif_carrier_on() and netif_carrier_off()
+//11.08/06/2008 - by river@aspeed
+//   Fix the timer did not work after device closed
+// SDK0.22
+//12.08/12/2008 - by river@aspeed
+//   Support different PHY configuration
+// SDK0.23
+//13.10/14/2008 - by river@aspeed
+//   Support Realtek RTL8211BN Gigabit PHY
+//14.11/17/2008 - by river@aspeed
+//   Modify the allocate buffer to alignment to IP header
+// SDK0.26
+//15.07/28/2009 - by river@aspeed
+//   Fix memory leakage problem in using multicast
+//16.07/28/2009 - by river@aspeed
+//   tx_free field in the local structure should be integer
+//
+//
+//
+//AST2300 SDK 0.12
+//17.03/30/2010 - by river@aspeed
+//   Modify for AST2300's hardware CLOCK/RESET/MULTI-PIN configuration
+//18.03/30/2010 - by river@aspeed
+//   Fix does not report netif_carrier_on() and netif_carrier_off() when use MARVELL PHY
+//AST2300 SDK 0.13
+//17.06/10/2010 - by river@aspeed
+//   Support AST2300 A0
+//18.06/10/2010 - by river@aspeed
+//   EEPROM is at I2C channel 4 on AST2300 A0 EVB
+//AST2300 SDK 0.14
+//19.09/13/2010 - by river@aspeed
+//   Support Realtek RTL8201EL 10/100M PHY
+//AST2400 
+//20.06/25/2013 - by CC@aspeed
+//   Support BCM54612E 10/100/1000M PHY
+//-----------------------------------------------------------------------------
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <mach/ftgmac100_drv.h>
+
+#include <linux/skbuff.h>
+
+#include "ftgmac100_26.h"
+
+#if defined(CONFIG_ARM)
+#include <mach/hardware.h>
+#include <asm/cacheflush.h>
+
+#elif defined(CONFIG_COLDFIRE)
+#include <asm/astsim.h>
+
+#else
+#err "Not define include for GMAC"
+#endif
+
+/*------------------------------------------------------------------------
+ .
+ . Configuration options, for the experienced user to change.
+ .
+ -------------------------------------------------------------------------*/
+
+/*
+ . DEBUGGING LEVELS
+ .
+ . 0 for normal operation
+ . 1 for slightly more details
+ . >2 for various levels of increasingly useless information
+ .    2 for interrupt tracking, status flags
+ .    3 for packet info
+ .    4 for complete packet dumps
+*/
+
+#define DO_PRINT(args...) printk(": " args)
+
+#define FTMAC100_DEBUG  1
+
+#if (FTMAC100_DEBUG > 2 )
+#define PRINTK3(args...) DO_PRINT(args)
+#else
+#define PRINTK3(args...)
+#endif
+
+#if FTMAC100_DEBUG > 1
+#define PRINTK2(args...) DO_PRINT(args)
+#else
+#define PRINTK2(args...)
+#endif
+
+#ifdef FTMAC100_DEBUG
+#define PRINTK(args...) DO_PRINT(args)
+#else
+#define PRINTK(args...)
+#endif
+
+/*
+ . A rather simple routine to print out a packet for debugging purposes.
+*/
+#if FTMAC100_DEBUG > 2
+static void print_packet( u8 *, int );
+#endif
+
+static int ftgmac100_wait_to_send_packet(struct sk_buff * skb, struct net_device * dev);
+
+static volatile int trans_busy = 0;
+
+
+void ftgmac100_phy_rw_waiting(unsigned int ioaddr)
+{
+	unsigned int tmp;
+
+	do {
+		mdelay(10);
+		tmp =inl(ioaddr + PHYCR_REG);
+	} while ((tmp&(PHY_READ_bit|PHY_WRITE_bit)) > 0);
+}
+
+
+/*------------------------------------------------------------
+ . Reads a register from the MII Management serial interface
+ .-------------------------------------------------------------*/
+static u16 ftgmac100_read_phy_register(unsigned int ioaddr, u8 phyaddr, u8 phyreg)
+{
+	unsigned int tmp;
+
+	if (phyaddr > 0x1f)	// MII chip IDs are 5 bits long
+	    return 0xffff;
+
+	tmp = inl(ioaddr + PHYCR_REG);
+	tmp &= 0x3000003F;
+	tmp |=(phyaddr<<16);
+	tmp |=(phyreg<<(16+5));
+	tmp |=PHY_READ_bit;
+
+	outl( tmp, ioaddr + PHYCR_REG );
+	ftgmac100_phy_rw_waiting(ioaddr);
+
+	return (inl(ioaddr + PHYDATA_REG)>>16);
+}
+
+
+/*------------------------------------------------------------
+ . Writes a register to the MII Management serial interface
+ .-------------------------------------------------------------*/
+static void ftgmac100_write_phy_register(unsigned int ioaddr,
+	u8 phyaddr, u8 phyreg, u16 phydata)
+{
+	unsigned int tmp;
+
+	if (phyaddr > 0x1f)	// MII chip IDs are 5 bits long
+	    return;
+
+	tmp = inl(ioaddr + PHYCR_REG);
+	tmp &= 0x3000003F;
+	tmp |=(phyaddr<<16);
+	tmp |=(phyreg<<(16+5));
+	tmp |=PHY_WRITE_bit;
+
+	outl( phydata, ioaddr + PHYDATA_REG );
+	outl( tmp, ioaddr + PHYCR_REG );
+	ftgmac100_phy_rw_waiting(ioaddr);
+}
+
+static void ast_gmac_set_mac(struct ftgmac100_priv *priv, const unsigned char *mac)
+{
+	unsigned int maddr = mac[0] << 8 | mac[1];
+	unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
+
+	iowrite32(maddr, priv->netdev->base_addr + MAC_MADR_REG);
+	iowrite32(laddr, priv->netdev->base_addr + MAC_LADR_REG);
+}
+
+/*
+ * MAC1 always has MII MDC+MDIO pins to access PHY registers.  We assume MAC1
+ * always has a PHY chip, if MAC1 is enabled.
+ * U-Boot can enable MAC2 MDC+MDIO pins for a 2nd PHY, or MAC2 might be
+ * disabled (only one port), or it's sideband-RMII which has no PHY chip.
+ *
+ * Return miiPhyId==0 if the MAC cannot be accessed.
+ * Return miiPhyId==1 if the MAC registers are OK but it cannot carry traffic.
+ * Return miiPhyId==2 if the MAC can send/receive but it has no PHY chip.
+ * Else return the PHY 22-bit vendor ID, 6-bit model and 4-bit revision.
+ */
+static void getMacHwConfig( struct net_device* dev, struct AstMacHwConfig* out )
+{
+	struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+
+//	out->macId   = dev->dev_id;
+//..	getMacAndPhy(dev, out);
+	out->miiPhyId = 0;
+
+	// We assume the Clock Stop register does not disable the MAC1 or MAC2 clock
+	// unless Reset Control also holds the MAC in reset.
+	// For now, we only support a PHY chip on the MAC's own MDC+MDIO bus.
+	if (out->phyAddr > 0x1f) {
+no_phy_access:
+	out->phyAddr = 0xff;
+	return;
+	}
+
+	if (priv->NCSI_support == 0) {
+		out->miiPhyId = ftgmac100_read_phy_register(dev->base_addr, out->phyAddr, 0x02);
+		if (out->miiPhyId == 0xFFFF) { //Realtek PHY at address 1
+			out->phyAddr = 1;
+		}
+		if (out->miiPhyId == 0x0362) { 
+			out->phyAddr = 1;
+		}
+		out->miiPhyId = ftgmac100_read_phy_register(dev->base_addr, out->phyAddr, 0x02);
+		out->miiPhyId = (out->miiPhyId & 0xffff) << 16;
+		out->miiPhyId |= ftgmac100_read_phy_register(dev->base_addr, out->phyAddr, 0x03) & 0xffff;
+
+		switch (out->miiPhyId >> 16) {
+		case 0x0040:	// Broadcom
+		case 0x0141:	// Marvell
+		case 0x001c:	// Realtek
+		case 0x0362:	// BCM54612
+		break;
+
+		default:
+		// Leave miiPhyId for DO_PRINT(), but reset phyAddr.
+		// out->miiPhyId = 2;
+		goto no_phy_access;
+		break;
+		}
+	}
+	return;
+}
+
+
+static void ftgmac100_reset( struct net_device* dev )
+{
+	struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+	struct AstMacHwConfig* ids = &priv->ids;
+	unsigned int tmp, speed, duplex;
+
+	getMacHwConfig(dev, ids);
+	PRINTK("%s:ftgmac100_reset, phyAddr=0x%x, miiPhyId=0x%04x_%04x\n",
+	       dev->name, ids->phyAddr, (ids->miiPhyId >> 16), (ids->miiPhyId & 0xffff));
+
+	if (ids->miiPhyId < 1)
+	    return;	// Cannot access MAC registers
+
+	// Check the link speed and duplex.
+	// They are not valid until auto-neg is resolved, which is reg.1 bit[5],
+	// or the link is up, which is reg.1 bit[2].
+
+	if (ids->phyAddr < 0xff)
+	    tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x1);
+	else tmp = 0;
+
+	if (0==(tmp & (1u<<5 | 1u<<2)) || ids->phyAddr >= 0xff) {
+	    // No PHY chip, or link has not negotiated.
+	    speed  = PHY_SPEED_100M;
+	    duplex = 1;
+	    netif_carrier_off(dev);
+	}
+	else if (((ids->miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL)) {
+	    tmp    = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x00);
+	    duplex = (tmp & 0x0100) ? 1 : 0;
+	    speed  = (tmp & 0x2000) ? PHY_SPEED_100M : PHY_SPEED_10M;
+	}
+	else if (((ids->miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) || 
+		 ((ids->miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
+	    // Use reg.17_0.bit[15:13] for {speed[1:0], duplex}.
+	    tmp    = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x11);
+	    duplex = (tmp & PHY_DUPLEX_mask)>>13;
+	    speed  = (tmp & PHY_SPEED_mask)>>14;
+	    netif_carrier_on(dev);
+	}
+	else if (priv->ids.miiPhyId == PHYID_BCM54612E) { 
+       // Get link status
+        // First Switch shadow register selector
+        ftgmac100_write_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C, 0x2000);
+        tmp    = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C);
+        if ( (tmp & 0x0080) == 0x0080 )
+            duplex = 0;
+        else
+            duplex = 1;
+        
+        switch(tmp & 0x0018) {
+            case 0x0000:
+                speed = PHY_SPEED_1G; break;
+            case 0x0008:    
+                speed = PHY_SPEED_100M; break;
+            case 0x0010:    
+                speed = PHY_SPEED_10M; break;
+            default:
+                speed = PHY_SPEED_100M;
+        } 
+    }
+	else {
+	    // Assume Broadcom BCM5221.  Use reg.18 bits [1:0] for {100Mb/s, fdx}.
+	    tmp    = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x18);
+	    duplex = (tmp & 0x0001);
+	    speed  = (tmp & 0x0002) ? PHY_SPEED_100M : PHY_SPEED_10M;
+	}
+
+	if (speed == PHY_SPEED_1G) {
+	    // Set SPEED_100_bit too, for consistency.
+	    priv->maccr_val |= GMAC_MODE_bit | SPEED_100_bit;
+	    tmp = inl( dev->base_addr + MACCR_REG );
+	    tmp |= GMAC_MODE_bit | SPEED_100_bit;
+	    outl(tmp, dev->base_addr + MACCR_REG );
+	} else {
+	    priv->maccr_val &= ~(GMAC_MODE_bit | SPEED_100_bit);
+	    tmp = inl( dev->base_addr + MACCR_REG );
+	    tmp &= ~(GMAC_MODE_bit | SPEED_100_bit);
+	    if (speed == PHY_SPEED_100M) {
+		priv->maccr_val |= SPEED_100_bit;
+		tmp |= SPEED_100_bit;
+	    }
+	    outl(tmp, dev->base_addr + MACCR_REG );
+	}
+	if (duplex)
+	    priv->maccr_val |= FULLDUP_bit;
+    else 
+		priv->maccr_val &= ~FULLDUP_bit;
+		
+	outl( SW_RST_bit, dev->base_addr + MACCR_REG );
+
+#ifdef not_complete_yet
+	/* Setup for fast accesses if requested */
+	/* If the card/system can't handle it then there will */
+	/* be no recovery except for a hard reset or power cycle */
+	if (dev->dma)
+	{
+		outw( inw( dev->base_addr + CONFIG_REG ) | CONFIG_NO_WAIT,
+		      dev->base_addr + CONFIG_REG );
+	}
+#endif /* end_of_not */
+
+	/* this should pause enough for the chip to be happy */
+	for (; (inl( dev->base_addr + MACCR_REG ) & SW_RST_bit) != 0; )
+	{
+		mdelay(10);
+		PRINTK3("RESET: reset not complete yet\n" );
+	}
+
+	outl( 0, dev->base_addr + IER_REG );			/* Disable all interrupts */
+}
+
+static void ftgmac100_enable( struct net_device *dev )
+{
+	int i;
+	struct ftgmac100_priv *priv 	= (struct ftgmac100_priv *)dev->priv;
+	unsigned int tmp_rsize;		//Richard
+	unsigned int rfifo_rsize;	//Richard
+	unsigned int tfifo_rsize;	//Richard
+	unsigned int rxbuf_size;
+
+	rxbuf_size = RX_BUF_SIZE & 0x3fff;
+	outl( rxbuf_size , dev->base_addr + RBSR_REG); //for NC Body
+
+	for (i=0; i<RXDES_NUM; ++i)
+		priv->rx_descs[i].RXPKT_RDY = RX_OWNBY_FTGMAC100;				// owned by FTMAC100
+
+	priv->rx_idx = 0;
+
+	for (i=0; i<TXDES_NUM; ++i) {
+		priv->tx_descs[i].TXDMA_OWN = TX_OWNBY_SOFTWARE;			// owned by software
+		priv->tx_skbuff[i] = 0;
+	}
+
+	priv->tx_idx = 0;
+	priv->old_tx = 0;
+	priv->tx_free=TXDES_NUM;
+
+	/* Set the MAC address */
+	ast_gmac_set_mac(priv, dev->dev_addr);
+
+	outl( priv->rx_descs_dma, dev->base_addr + RXR_BADR_REG);
+	outl( priv->tx_descs_dma, dev->base_addr + TXR_BADR_REG);
+	outl( 0x00001010, dev->base_addr + ITC_REG);
+
+	outl( (0UL<<TXPOLL_CNT)|(0x1<<RXPOLL_CNT), dev->base_addr + APTC_REG);
+	outl( 0x44f97, dev->base_addr + DBLAC_REG );
+
+	///	outl( inl(FCR_REG)|0x1, ioaddr + FCR_REG );				// enable flow control
+	///	outl( inl(BPR_REG)|0x1, ioaddr + BPR_REG );				// enable back pressure register
+
+	// +++++ Richard +++++ //
+	tmp_rsize = inl( dev->base_addr + FEAR_REG );
+	rfifo_rsize = tmp_rsize & 0x00000007;
+	tfifo_rsize = (tmp_rsize >> 3)& 0x00000007;
+
+	tmp_rsize = inl( dev->base_addr + TPAFCR_REG );
+	tmp_rsize &= ~0x3f000000;
+	tmp_rsize |= (tfifo_rsize << 27);
+	tmp_rsize |= (rfifo_rsize << 24);
+
+	outl(tmp_rsize, dev->base_addr + TPAFCR_REG);
+	// ----- Richard ----- //
+
+//river set MAHT0, MAHT1
+	if (priv->maccr_val & GMAC_MODE_bit) {
+		outl (priv->GigaBit_MAHT0, dev->base_addr + MAHT0_REG);
+		outl (priv->GigaBit_MAHT1, dev->base_addr + MAHT1_REG);
+	}
+	else {
+		outl (priv->Not_GigaBit_MAHT0, dev->base_addr + MAHT0_REG);
+		outl (priv->Not_GigaBit_MAHT1, dev->base_addr + MAHT1_REG);
+	}
+
+	/// enable trans/recv,...
+	outl(priv->maccr_val, dev->base_addr + MACCR_REG );
+#if 0	
+//NCSI Start
+//DeSelect Package/ Select Package
+	if ((priv->NCSI_support == 1) || (priv->INTEL_NCSI_EVA_support == 1)) {
+		NCSI_Struct_Initialize(dev);
+		for (i = 0; i < 4; i++) {
+			DeSelect_Package (dev, i);
+			Package_Found = Select_Package (dev, i);
+			if (Package_Found == 1) {
+//AST2100/AST2050/AST1100 supports 1 slave only
+				priv->NCSI_Cap.Package_ID = i;
+				break;
+			}
+		}
+		if (Package_Found != 0) {
+//Initiali State
+			for (i = 0; i < 2; i++) { //Suppose 2 channels in current version, You could modify it to 0x1F to support 31 channels
+				Channel_Found = Clear_Initial_State(dev, i);
+				if (Channel_Found == 1) {
+					priv->NCSI_Cap.Channel_ID = i;
+					printk ("Found NCSI Network Controller at (%d, %d)\n", priv->NCSI_Cap.Package_ID, priv->NCSI_Cap.Channel_ID);
+//Get Version and Capabilities
+					Get_Version_ID(dev);
+					Get_Capabilities(dev);
+//Configuration
+					Select_Active_Package(dev);
+//Set MAC Address
+					Enable_Set_MAC_Address(dev);
+//Enable Broadcast Filter
+					Enable_Broadcast_Filter(dev);
+//Disable VLAN
+					Disable_VLAN(dev);
+//Enable AEN
+					Enable_AEN(dev);
+//Get Parameters
+					Get_Parameters(dev);
+//Enable TX	
+					Enable_Network_TX(dev);
+//Enable Channel
+					Enable_Channel(dev);
+//Get Link Status
+Re_Get_Link_Status:
+					Link_Status = Get_Link_Status(dev);
+					if (Link_Status == LINK_UP) {
+						printk ("Using NCSI Network Controller (%d, %d)\n", priv->NCSI_Cap.Package_ID, priv->NCSI_Cap.Channel_ID);
+						netif_carrier_on(dev);
+						break;
+					}
+					else if ((Link_Status == LINK_DOWN) && (Re_Send < 2)) {
+						Re_Send++;
+						netif_carrier_off(dev);
+						goto Re_Get_Link_Status;
+					}
+//Disable TX	
+					Disable_Network_TX(dev);
+//Disable Channel
+//					Disable_Channel(dev);
+					Re_Send = 0;
+					Channel_Found = 0;
+				}
+			}
+		}
+	}
+	/* now, enable interrupts */
+#endif
+	if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
+	    ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
+		outl(
+			PHYSTS_CHG_bit		|
+			AHB_ERR_bit			|
+			TPKT_LOST_bit		|
+			TPKT2E_bit			|
+			RXBUF_UNAVA_bit		|
+			RPKT2B_bit
+        	,dev->base_addr + IER_REG
+       	 	);
+	}
+	else if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) ||
+		 ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL)) {
+		outl(
+			AHB_ERR_bit			|
+			TPKT_LOST_bit		|
+			TPKT2E_bit			|
+			RXBUF_UNAVA_bit		|
+			RPKT2B_bit
+        	,dev->base_addr + IER_REG
+       	 	);
+	}
+	else if (priv->ids.miiPhyId == PHYID_BCM54612E) { 
+        outl(
+// no link PHY link status pin            PHYSTS_CHG_bit      |
+            AHB_ERR_bit         |
+            TPKT_LOST_bit       |
+            TPKT2E_bit          |
+            RXBUF_UNAVA_bit     |
+            RPKT2B_bit
+            ,dev->base_addr + IER_REG
+            );
+    } else {
+		outl(
+// no link PHY link status pin			  PHYSTS_CHG_bit	  |
+			AHB_ERR_bit 		|
+			TPKT_LOST_bit		|
+			TPKT2E_bit			|
+			RXBUF_UNAVA_bit 	|
+			RPKT2B_bit
+			,dev->base_addr + IER_REG
+			);    
+    }
+}
+
+static void aspeed_mac_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+	unsigned int status, tmp, speed, duplex, macSpeed;
+
+#ifdef CONFIG_ARCH_AST2300
+	//Fix issue for tx/rx arbiter lock
+	outl( 0xffffffff, dev->base_addr + TXPD_REG);
+#endif
+	status = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x01);
+
+	if (status & LINK_STATUS) { // Bit[2], Link Status, link is up
+	    priv->timer.expires = jiffies + 10 * HZ;
+
+	if ((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) {
+	    tmp    = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x18);
+	    duplex = (tmp & 0x0001);
+	    speed  = (tmp & 0x0002) ? PHY_SPEED_100M : PHY_SPEED_10M;
+	}
+	else if ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL) {
+	    tmp    = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x00);
+	    duplex = (tmp & 0x0100) ? 1 : 0;
+	    speed  = (tmp & 0x2000) ? PHY_SPEED_100M : PHY_SPEED_10M;
+	}
+	else if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
+		 ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
+	    tmp    = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x11);
+	    duplex = (tmp & PHY_DUPLEX_mask)>>13;
+	    speed  = (tmp & PHY_SPEED_mask)>>14;
+	}
+	else if (priv->ids.miiPhyId == PHYID_BCM54612E) { 
+	    // Get link status
+	    // First Switch shadow register selector
+	    ftgmac100_write_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C, 0x2000);
+	    tmp    = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C);
+	    if ( (tmp & 0x0080) == 0x0080 )
+	        duplex = 0;
+	    else
+	        duplex = 1;
+	                               
+	    switch(tmp & 0x0018) {
+	        case 0x0000:
+	            speed = PHY_SPEED_1G; 
+	    
+	            break;
+	        case 0x0008:    
+	            speed = PHY_SPEED_100M; 
+	                   
+	            break;
+	        case 0x0010:    
+	            speed = PHY_SPEED_10M; 
+	                                       
+	            break;
+	        default:
+	            speed = PHY_SPEED_100M;
+	    } 
+	}
+	else {
+	    duplex = 1;  speed = PHY_SPEED_100M;
+	}
+
+	macSpeed = ((priv->maccr_val & GMAC_MODE_bit)>>8   // Move bit[9] to bit[1]
+		    | (priv->maccr_val & SPEED_100_bit)>>19);  // bit[19] to bit[0]
+	// The MAC hardware ignores SPEED_100_bit if GMAC_MODE_bit is set.
+	if (macSpeed > PHY_SPEED_1G) macSpeed = PHY_SPEED_1G;	// 0x3 --> 0x2
+
+	if ( ((priv->maccr_val & FULLDUP_bit)!=0) != duplex
+	     || macSpeed != speed )
+	{
+		PRINTK("%s:aspeed_mac_timer, priv->maccr_val=0x%05x, PHY {speed,duplex}=%d,%d\n",
+		   dev->name, priv->maccr_val, speed, duplex);
+		ftgmac100_reset(dev);
+		ftgmac100_enable(dev);
+	}
+	    netif_carrier_on(dev);
+	}
+	else {
+	netif_carrier_off(dev);
+	    priv->timer.expires = jiffies + 1 * HZ;
+	}
+	add_timer(&priv->timer);
+}
+
+/*
+ . Function: ftgmac100_shutdown
+ . Purpose:  closes down the SMC91xxx chip.
+ . Method:
+ .	1. zero the interrupt mask
+ .	2. clear the enable receive flag
+ .	3. clear the enable xmit flags
+ .
+ . TODO:
+ .   (1) maybe utilize power down mode.
+ .	Why not yet?  Because while the chip will go into power down mode,
+ .	the manual says that it will wake up in response to any I/O requests
+ .	in the register space.   Empirical results do not show this working.
+*/
+static void ftgmac100_shutdown( unsigned int ioaddr )
+{
+	///interrupt mask register
+	outl( 0, ioaddr + IER_REG );
+	/* enable trans/recv,... */
+	outl( 0, ioaddr + MACCR_REG );
+}
+
+/*
+ . Function: ftgmac100_wait_to_send_packet( struct sk_buff * skb, struct device * )
+ . Purpose:
+ .    Attempt to allocate memory for a packet, if chip-memory is not
+ .    available, then tell the card to generate an interrupt when it
+ .    is available.
+ .
+ . Algorithm:
+ .
+ . o	if the saved_skb is not currently null, then drop this packet
+ .		on the floor.  This should never happen, because of TBUSY.
+ . o	if the saved_skb is null, then replace it with the current packet,
+ . o	See if I can sending it now.
+ . o 	(NO): Enable interrupts and let the interrupt handler deal with it.
+ . o	(YES):Send it now.
+*/
+static int ftgmac100_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev )
+{
+	struct ftgmac100_priv *priv 	= (struct ftgmac100_priv *)dev->priv;
+	unsigned long ioaddr 	= dev->base_addr;
+	volatile TX_DESC *cur_desc;
+	int		length;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->tx_lock,flags);
+
+	if (skb==NULL)
+	{
+		DO_PRINT("%s(%d): NULL skb???\n", __FILE__,__LINE__);
+		spin_unlock_irqrestore(&priv->tx_lock, flags);
+		return 0;
+	}
+
+	PRINTK3("%s:ftgmac100_wait_to_send_packet, skb=%x\n", dev->name, skb);
+	cur_desc = &priv->tx_descs[priv->tx_idx];
+
+#ifdef not_complete_yet	
+	if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE)		/// no empty transmit descriptor 
+	{
+		DO_PRINT("no empty transmit descriptor\n");
+		DO_PRINT("jiffies = %d\n", jiffies);
+		priv->stats.tx_dropped++;
+		netif_stop_queue(dev);		/// waiting to do: 
+		spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+		return 1;
+   	}
+#endif /* end_of_not */
+
+	if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE)		/// no empty transmit descriptor 
+	{
+		DO_PRINT("no empty TX descriptor:0x%x:0x%x\n",
+				(unsigned int)cur_desc,((unsigned int *)cur_desc)[0]);
+		priv->stats.tx_dropped++;
+		netif_stop_queue(dev);		/// waiting to do: 
+		spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+		return 1;
+   	}
+	priv->tx_skbuff[priv->tx_idx] = skb;
+	length = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
+	length = min(length, TX_BUF_SIZE);
+
+#if FTMAC100_DEBUG > 2
+	DO_PRINT("Transmitting Packet at 0x%x, skb->data = %x, len = %x\n",
+		 (unsigned int)cur_desc->VIR_TXBUF_BADR, skb->data, length);
+	print_packet( skb->data, length );
+#endif
+
+	cur_desc->VIR_TXBUF_BADR = (unsigned long)skb->data;
+	cur_desc->TXBUF_BADR = virt_to_phys(skb->data);
+#ifndef CONFIG_CPU_FA52x_DCE
+	dmac_clean_range((void *)skb->data, (void *)(skb->data + length));
+#endif
+
+	//clean_dcache_range(skb->data, (char*)(skb->data + length));
+
+	cur_desc->TXBUF_Size = length;
+	cur_desc->LTS = 1;
+	cur_desc->FTS = 1;
+
+	cur_desc->TX2FIC = 0;
+	cur_desc->TXIC = 0;
+
+	cur_desc->TXDMA_OWN = TX_OWNBY_FTGMAC100;
+
+	outl( 0xffffffff, ioaddr + TXPD_REG);
+
+	priv->tx_idx = (priv->tx_idx + 1) % TXDES_NUM;
+	priv->stats.tx_packets++;
+	priv->tx_free--;
+
+	if (priv->tx_free <= 0) {
+		netif_stop_queue(dev);
+
+	}
+
+
+	dev->trans_start = jiffies;
+	spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+	return 0;
+}
+
+static int ftgmac100_ringbuf_alloc(struct ftgmac100_priv *priv)
+{
+	int i;
+	struct sk_buff *skb;
+
+    priv->rx_descs = dma_alloc_coherent(priv->dev, 
+								sizeof(RX_DESC)*RXDES_NUM, 
+								&priv->rx_descs_dma, GFP_KERNEL);
+
+	if(!priv->rx_descs)
+		return -ENOMEM;
+	
+	memset(priv->rx_descs, 0, sizeof(RX_DESC)*RXDES_NUM);
+	priv->rx_descs[RXDES_NUM-1].EDORR = 1;
+
+	for (i=0; i<RXDES_NUM; i++) {
+		dma_addr_t mapping;	
+		skb = dev_alloc_skb(RX_BUF_SIZE + NET_IP_ALIGN);
+		skb_reserve(skb, NET_IP_ALIGN);
+
+		priv->rx_skbuff[i] = skb;
+		if (skb == NULL) {
+			printk ("alloc_list: allocate Rx buffer error! ");
+			break;
+		}
+		mapping = dma_map_single(priv->dev, skb->data, skb->len, DMA_FROM_DEVICE);
+		skb->dev = priv->netdev;	/* Mark as being used by this device. */
+		priv->rx_descs[i].RXBUF_BADR = mapping;
+		priv->rx_descs[i].VIR_RXBUF_BADR = skb->data;
+	}
+
+	priv->tx_descs = dma_alloc_coherent(priv->dev, 
+						sizeof(TX_DESC)*TXDES_NUM, 
+						&priv->tx_descs_dma ,GFP_KERNEL);
+
+	if(!priv->tx_descs)
+		return -ENOMEM;
+
+	memset((void*)priv->tx_descs, 0, sizeof(TX_DESC)*TXDES_NUM);
+	priv->tx_descs[TXDES_NUM-1].EDOTR = 1;			// is last descriptor
+	
+}
+
+#if FTMAC100_DEBUG > 2
+static void print_packet( u8 * buf, int length )
+{
+#if 1
+#if FTMAC100_DEBUG > 3
+	int i;
+	int remainder;
+	int lines;
+#endif
+
+
+#if FTMAC100_DEBUG > 3
+	lines = length / 16;
+	remainder = length % 16;
+
+	for ( i = 0; i < lines ; i ++ ) {
+		int cur;
+
+		for ( cur = 0; cur < 8; cur ++ ) {
+			u8 a, b;
+
+			a = *(buf ++ );
+			b = *(buf ++ );
+			DO_PRINT("%02x%02x ", a, b );
+		}
+		DO_PRINT("\n");
+	}
+	for ( i = 0; i < remainder/2 ; i++ ) {
+		u8 a, b;
+
+		a = *(buf ++ );
+		b = *(buf ++ );
+		DO_PRINT("%02x%02x ", a, b );
+	}
+	DO_PRINT("\n");
+#endif
+#endif
+}
+#endif
+
+/*------------------------------------------------------------
+ . Configures the specified PHY using Autonegotiation.
+ .-------------------------------------------------------------*/
+static void ftgmac100_phy_configure(struct net_device* dev)
+{
+    struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+	u32 tmp;
+//	printk("priv->ids.miiPhyId = %x \n",priv->ids.miiPhyId);
+	switch (priv->ids.miiPhyId & PHYID_VENDOR_MASK) {
+		case PHYID_VENDOR_MARVELL:
+			ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x12, 0x4400);
+			tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x13 );
+			break;
+		case PHYID_VENDOR_REALTEK:
+			switch (priv->ids.miiPhyId) {
+				case PHYID_RTL8211:
+					ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x12, 0x4400);
+					tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x13 );
+					break;
+				case PHYID_RTL8201EL:
+					break;
+				case PHYID_RTL8201F:
+					ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1f, 0x0007);
+					tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x13 );
+					tmp &= ~(0x0030);
+					tmp |= 0x0008;
+					ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x13, (u16) tmp);
+					tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x11);
+					tmp &= ~(0x0fff);
+					tmp |= 0x0008;
+					ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x11, (u16) tmp);
+					ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1f, 0x0000);
+					break;
+			}
+			break;
+		case PHYID_VENDOR_BROADCOM:
+			switch (priv->ids.miiPhyId) {
+				case PHYID_BCM54612E:
+					ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1C, 0x8C00); // Disable GTXCLK Clock Delay Enable
+					ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x18, 0xF0E7); // Disable RGMII RXD to RXC Skew
+					break;			
+				case PHYID_BCM5221A4:
+				default:
+					tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x1b);
+					tmp |= 0x0004;
+					ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1b, (u16) tmp);
+					break;
+				}
+			break;			
+		}
+}
+
+
+/*--------------------------------------------------------
+ . Called by the kernel to send a packet out into the void
+ . of the net.  This routine is largely based on
+ . skeleton.c, from Becker.
+ .--------------------------------------------------------
+*/
+static void ftgmac100_timeout (struct net_device *dev)
+{
+	/* If we get here, some higher level has decided we are broken.
+	There should really be a "kick me" function call instead. */
+	DO_PRINT(KERN_WARNING "%s: transmit timed out? (jiffies=%ld)\n",
+		 dev->name, jiffies);
+	/* "kick" the adaptor */
+	ftgmac100_reset( dev );
+	ftgmac100_enable( dev );
+
+	/* Reconfigure the PHY */
+	ftgmac100_phy_configure(dev);
+
+	netif_wake_queue(dev);
+	dev->trans_start = jiffies;
+}
+
+
+static void ftgmac100_free_tx (struct net_device *dev) 
+{
+ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+ int entry = priv->old_tx % TXDES_NUM; 
+ unsigned long flags = 0;
+ 
+ spin_lock_irqsave(&priv->tx_lock,flags);
+ 
+ /* Free used tx skbuffs */
+
+  while ((priv->tx_descs[entry].TXDMA_OWN == TX_OWNBY_SOFTWARE) && (priv->tx_skbuff[entry] != NULL)) {
+  struct sk_buff *skb;
+  
+  skb = priv->tx_skbuff[entry];
+         dev_kfree_skb_any (skb);
+  priv->tx_skbuff[entry] = 0;
+  entry = (entry + 1) % TXDES_NUM;
+  priv->tx_free++;
+ }
+ 
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ priv->old_tx = entry;
+ if ((netif_queue_stopped(dev)) && (priv->tx_free > 0)) {
+ 	netif_wake_queue (dev);
+ }
+}
+
+
+/*-------------------------------------------------------------
+ .
+ . ftgmac100_rcv -  receive a packet from the card
+ .
+ . There is ( at least ) a packet waiting to be read from
+ . chip-memory.
+ .
+ . o Read the status
+ . o If an error, record it
+ . o otherwise, read in the packet
+ --------------------------------------------------------------
+*/
+// extern dce_dcache_invalidate_range(unsigned int start, unsigned int end);
+
+static void ftgmac100_rcv(struct net_device *dev)
+{
+	struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+	unsigned long ioaddr 	= dev->base_addr;
+	int 	packet_length;
+	int 	rcv_cnt;
+	volatile RX_DESC *cur_desc;
+	int		cur_idx;
+	int		have_package;
+	int		have_frs;
+	int	 	start_idx;
+        int             count = 0;
+        int             packet_full = 0;
+	int		data_not_fragment = 1;
+
+	start_idx = priv->rx_idx;
+
+	for (rcv_cnt=0; rcv_cnt<RXDES_NUM ; ++rcv_cnt)
+	{
+		packet_length = 0;
+		cur_idx = priv->rx_idx;
+
+		have_package = 0;
+		have_frs = 0;
+
+		for (; (cur_desc = &priv->rx_descs[priv->rx_idx])->RXPKT_RDY==RX_OWNBY_SOFTWARE; )
+		{
+			have_package = 1;
+			priv->rx_idx = (priv->rx_idx+1)%RXDES_NUM;
+                        count++;
+                        if (count == RXDES_NUM) {
+                            packet_full = 1;
+                        }
+//DF_support
+                            if (data_not_fragment == 1) {
+                                if (!(cur_desc->DF)) {
+                                    data_not_fragment = 0;
+                                }
+                            }
+
+			if (cur_desc->FRS)
+			{
+				have_frs = 1;
+				if (cur_desc->RX_ERR || cur_desc->CRC_ERR || cur_desc->FTL ||
+				    cur_desc->RUNT || cur_desc->RX_ODD_NB
+				    // cur_desc->IPCS_FAIL || cur_desc->UDPCS_FAIL || cur_desc->TCPCS_FAIL
+				    )
+				{
+				//	#ifdef not_complete_yet
+					if (cur_desc->RX_ERR)
+					{
+						DO_PRINT("err: RX_ERR\n");
+					}
+					if (cur_desc->CRC_ERR)
+					{
+				//		DO_PRINT("err: CRC_ERR\n");
+					}
+					if (cur_desc->FTL)
+					{
+						DO_PRINT("err: FTL\n");
+					}
+					if (cur_desc->RX_ODD_NB)
+					{
+				//		DO_PRINT("err: RX_ODD_NB\n");
+				        }
+//				        if (cur_desc->IPCS_FAIL || cur_desc->UDPCS_FAIL || cur_desc->TCPCS_FAIL)
+//				        {
+//				        	DO_PRINT("err: CS FAIL\n");
+//				        }
+				//	#endif /* end_of_not */
+					priv->stats.rx_errors++;			// error frame....
+					break;
+				}
+//DF_support
+                                    if (cur_desc->DF) {
+				        if (cur_desc->IPCS_FAIL || cur_desc->UDPCS_FAIL || cur_desc->TCPCS_FAIL)
+				        {
+				        	DO_PRINT("err: CS FAIL\n");
+					        priv->stats.rx_errors++;			// error frame....
+                                                break;
+				        }
+                                    }
+
+				if (cur_desc->MULTICAST)
+				{
+					priv->stats.multicast++;
+				}
+				if ((priv->NCSI_support == 1) || (priv->INTEL_NCSI_EVA_support == 1)) {
+					if (cur_desc->BROADCAST) {
+						if (*(unsigned short *)(cur_desc->VIR_RXBUF_BADR + 12) == NCSI_HEADER) {
+							printk ("AEN PACKET ARRIVED\n");
+							ftgmac100_reset(dev);
+							ftgmac100_enable(dev);
+							return;
+						}
+					}
+				}
+			}
+
+			packet_length += cur_desc->VDBC;
+
+//			if ( cur_desc->LRS )		// packet's last frame
+//			{
+				break;
+//			}
+		}
+		if (have_package==0)
+		{
+			goto done;
+		}
+		if (!have_frs)
+		{
+			DO_PRINT("error, loss first\n");
+			priv->stats.rx_over_errors++;
+		}
+
+		if (packet_length > 0)
+		{
+			struct sk_buff  * skb;
+			u8		* data = 0;  if (data) { }
+
+			packet_length -= 4;
+
+			skb_put (skb = priv->rx_skbuff[cur_idx], packet_length);
+
+// Rx Offload DF_support
+
+			    if (data_not_fragment) {
+				skb->ip_summed = CHECKSUM_UNNECESSARY;
+                                data_not_fragment = 1;
+                            }
+
+#if FTMAC100_DEBUG > 2
+			DO_PRINT("Receiving Packet at 0x%x, packet len = %x\n",(unsigned int)data, packet_length);
+			print_packet( data, packet_length );
+#endif
+
+			skb->protocol = eth_type_trans(skb, dev );
+			netif_rx(skb);
+			priv->stats.rx_packets++;
+			priv->rx_skbuff[cur_idx] = NULL;
+		}
+                if (packet_full) {
+//                  DO_PRINT ("RX Buffer full before driver entered ISR\n");
+                    goto done;
+                }
+	}
+
+done:
+
+        if (packet_full) {
+
+		struct sk_buff *skb;
+
+		for (cur_idx = 0; cur_idx < RXDES_NUM; cur_idx++)
+		{
+			if (priv->rx_skbuff[cur_idx] == NULL) {
+				skb = dev_alloc_skb (RX_BUF_SIZE + 16);
+				if (skb == NULL) {
+					printk (KERN_INFO
+						"%s: receive_packet: "
+						"Unable to re-allocate Rx skbuff.#%d\n",
+						dev->name, cur_idx);
+				}
+				priv->rx_skbuff[cur_idx] = skb;
+				skb->dev = dev;
+				// ASPEED: See earlier skb_reserve() cache alignment
+				skb_reserve (skb, 2);
+				dmac_inv_range ((void *)skb->data, (void *)skb->data + RX_BUF_SIZE);
+				priv->rx_descs[cur_idx].RXBUF_BADR = cpu_to_le32(virt_to_phys(skb->tail));
+				priv->rx_descs[cur_idx].VIR_RXBUF_BADR = cpu_to_le32((u32)skb->tail);
+			}
+		        priv->rx_descs[cur_idx].RXPKT_RDY = RX_OWNBY_FTGMAC100;
+                }
+                packet_full = 0;
+
+        }
+	else {
+            if (start_idx != priv->rx_idx) {
+		struct sk_buff *skb;
+
+		for (cur_idx = (start_idx+1)%RXDES_NUM; cur_idx != priv->rx_idx; cur_idx = (cur_idx+1)%RXDES_NUM)
+		{
+
+
+			//struct sk_buff *skb;
+			/* Dropped packets don't need to re-allocate */
+			if (priv->rx_skbuff[cur_idx] == NULL) {
+				skb = dev_alloc_skb (RX_BUF_SIZE + 16);
+				if (skb == NULL) {
+					printk (KERN_INFO
+						"%s: receive_packet: "
+						"Unable to re-allocate Rx skbuff.#%d\n",
+						dev->name, cur_idx);
+					break;
+				}
+				priv->rx_skbuff[cur_idx] = skb;
+				skb->dev = dev;
+				/* 16 byte align the IP header */
+				skb_reserve (skb, 2);
+				dmac_inv_range ((void *)skb->data,
+						(void *)skb->data + RX_BUF_SIZE);
+				priv->rx_descs[cur_idx].RXBUF_BADR = cpu_to_le32(virt_to_phys(skb->tail));
+				priv->rx_descs[cur_idx].VIR_RXBUF_BADR = cpu_to_le32((u32)skb->tail);
+			}
+
+			priv->rx_descs[cur_idx].RXPKT_RDY = RX_OWNBY_FTGMAC100;
+		}
+
+
+			//struct sk_buff *skb;
+			/* Dropped packets don't need to re-allocate */
+			if (priv->rx_skbuff[start_idx] == NULL) {
+				skb = dev_alloc_skb (RX_BUF_SIZE + 16);
+				if (skb == NULL) {
+					printk (KERN_INFO
+						"%s: receive_packet: "
+						"Unable to re-allocate Rx skbuff.#%d\n",
+						dev->name, start_idx);
+				}
+				priv->rx_skbuff[start_idx] = skb;
+				skb->dev = dev;
+				/* 16 byte align the IP header */
+				skb_reserve (skb, 2);
+				dmac_inv_range ((void *)skb->data,
+						(void *)skb->data + RX_BUF_SIZE);
+				priv->rx_descs[start_idx].RXBUF_BADR = cpu_to_le32(virt_to_phys(skb->tail));
+				priv->rx_descs[start_idx].VIR_RXBUF_BADR = cpu_to_le32((u32)skb->tail);
+			}
+
+
+		priv->rx_descs[start_idx].RXPKT_RDY = RX_OWNBY_FTGMAC100;
+	    }
+    }
+	if (trans_busy == 1)
+	{
+		/// priv->maccr_val |= RXMAC_EN_bit;
+		outl( priv->maccr_val, ioaddr + MACCR_REG );
+		outl( inl(ioaddr + IER_REG) | RXBUF_UNAVA_bit, ioaddr + IER_REG);
+	}
+	return;
+}
+
+/*--------------------------------------------------------------------
+ .
+ . This is the main routine of the driver, to handle the net_device when
+ . it needs some attention.
+ .
+ . So:
+ .   first, save state of the chipset
+ .   branch off into routines to handle each case, and acknowledge
+ .	    each to the interrupt register
+ .   and finally restore state.
+ .
+ ---------------------------------------------------------------------*/
+static irqreturn_t ftgmac100_interrupt(int irq, void * dev_id,  struct pt_regs * regs)
+{
+	struct net_device *dev 	= dev_id;
+	struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+	unsigned long ioaddr 	= dev->base_addr;
+	int		timeout;
+	unsigned int tmp;
+	unsigned int	mask;			// interrupt mask
+	unsigned int	status;			// interrupt status
+
+//	PRINTK3("%s: ftgmac100 interrupt started \n", dev->name);
+
+	if (dev == NULL) {
+		DO_PRINT(KERN_WARNING "%s: irq %d for unknown device.\n",	dev->name, irq);
+		return IRQ_HANDLED;
+	}
+
+	/* read the interrupt status register */
+	mask = inl( ioaddr + IER_REG );
+
+	/* set a timeout value, so I don't stay here forever */
+
+	for (timeout=1; timeout>0; --timeout)
+	{
+		/* read the status flag, and mask it */
+		status = inl( ioaddr + ISR_REG ) & mask;
+
+		outl(status, ioaddr + ISR_REG ); //Richard, write to clear
+
+		if (!status )
+		{
+			break;
+		}
+
+		if (status & PHYSTS_CHG_bit) {
+		    DO_PRINT("PHYSTS_CHG \n");
+		    // Is this interrupt for changes of the PHYLINK pin?
+		    // Note: PHYLINK is optional; not all boards connect it.
+		    if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) || 
+		    	((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211))
+		    {
+			tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x13);
+			PRINTK("%s: PHY interrupt status, read_phy_reg(0x13) = 0x%04x\n",
+			       dev->name, tmp);
+			tmp &= (PHY_SPEED_CHG_bit | PHY_DUPLEX_CHG_bit | PHY_LINK_CHG_bit);
+		    }
+		    else if ((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM)
+		    {
+			tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x1a);
+			PRINTK("%s: PHY interrupt status, read_phy_reg(0x1a) = 0x%04x\n",
+			       dev->name, tmp);
+			// Bits [3:1] are {duplex, speed, link} change interrupts.
+			tmp &= 0x000e;
+		    }
+		    else if (priv->ids.miiPhyId == PHYID_BCM54612E) { 
+                tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x1A);
+                PRINTK("%s: PHY interrupt status, read_phy_reg(0x1A) = 0x%04x\n",
+                    dev->name, tmp);
+                tmp &= 0x000E;
+            }
+		    else tmp = 0;
+
+		    if (tmp) {
+			ftgmac100_reset(dev);
+			ftgmac100_enable(dev);
+		    }
+		}
+
+#ifdef not_complete_yet
+		if (status & AHB_ERR_bit)
+		{
+			DO_PRINT("AHB_ERR \n");
+		}
+
+		if (status & RPKT_LOST_bit)
+		{
+			DO_PRINT("RPKT_LOST ");
+		}
+		if (status & RPKT2F_bit)
+		{
+			PRINTK2("RPKT_SAV ");
+		}
+
+		if (status & TPKT_LOST_bit)
+		{
+			PRINTK("XPKT_LOST ");
+		}
+		if (status & TPKT2E_bit)
+		{
+			PRINTK("XPKT_OK ");
+		}
+		if (status & NPTXBUF_UNAVA_bit)
+		{
+			PRINTK("NOTXBUF ");
+		}
+		if (status & TPKT2F_bit)
+		{
+			PRINTK("XPKT_FINISH ");
+		}
+
+		if (status & RPKT2B_bit)
+		{
+			DO_PRINT("RPKT_FINISH ");
+		}
+		PRINTK2("\n");
+#endif /* end_of_not */
+
+//		PRINTK3(KERN_WARNING "%s: Handling interrupt status %x \n",	dev->name, status);
+
+		if ( status & (TPKT2E_bit|TPKT_LOST_bit))
+		{
+			//free tx skb buf
+			ftgmac100_free_tx(dev);
+
+		}
+
+		if ( status & RPKT2B_bit )
+		{
+			ftgmac100_rcv(dev); //Richard
+		}
+		else if (status & RXBUF_UNAVA_bit)
+		{
+			outl( mask & ~RXBUF_UNAVA_bit, ioaddr + IER_REG);
+			trans_busy = 1;
+		/*
+			rcv_tq.sync = 0;
+			rcv_tq.routine = ftgmac100_rcv;
+			rcv_tq.data = dev;
+			queue_task(&rcv_tq, &tq_timer);
+		*/
+
+		} else if (status & AHB_ERR_bit)
+		{
+			DO_PRINT("AHB ERR \n");
+		}
+	}
+
+//	PRINTK3("%s: Interrupt done\n", dev->name);
+	return IRQ_HANDLED;
+}
+
+/*------------------------------------------------------------
+ . Get the current statistics.
+ . This may be called with the card open or closed.
+ .-------------------------------------------------------------*/
+static struct net_device_stats* ftgmac100_query_statistics(struct net_device *dev) 
+{
+	struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+	
+	return &priv->stats;
+}
+
+#ifdef HAVE_MULTICAST
+
+// --------------------------------------------------------------------
+// 	Finds the CRC32 of a set of bytes.
+//	Again, from Peter Cammaert's code.
+// --------------------------------------------------------------------
+static int crc32( char * s, int length ) 
+{
+	/* indices */
+	int perByte;
+	int perBit;
+	/* crc polynomial for Ethernet */
+	const u32 poly = 0xedb88320;
+	/* crc value - preinitialized to all 1's */
+	u32 crc_value = 0xffffffff;
+
+	for ( perByte = 0; perByte < length; perByte ++ ) {
+		unsigned char	c;
+
+		c = *(s++);
+		for ( perBit = 0; perBit < 8; perBit++ ) {
+			crc_value = (crc_value>>1)^
+				(((crc_value^c)&0x01)?poly:0);
+			c >>= 1;
+		}
+	}
+	return	crc_value;
+}
+
+/*
+ . Function: ftgmac100_setmulticast( struct net_device *dev, int count, struct dev_mc_list * addrs )
+ . Purpose:
+ .    This sets the internal hardware table to filter out unwanted multicast
+ .    packets before they take up memory.
+*/
+
+static void ftgmac100_setmulticast( struct net_device *dev, int count, struct dev_mc_list * addrs ) 
+{
+	struct dev_mc_list	* cur_addr;
+	int crc_val;
+	unsigned int	ioaddr = dev->base_addr;
+	struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+	struct AstMacHwConfig* ids = &priv->ids;
+	unsigned long Combined_Channel_ID, i;
+	struct sk_buff * skb;
+	cur_addr = addrs;	
+
+//TX
+#if 0
+	if (priv->NCSI_support == 1) {
+		skb = dev_alloc_skb (TX_BUF_SIZE + 16);		
+		priv->InstanceID++;
+		priv->NCSI_Request.IID = priv->InstanceID;
+		priv->NCSI_Request.Command = SET_MAC_ADDRESS;
+		Combined_Channel_ID = (priv->NCSI_Cap.Package_ID << 5) + priv->NCSI_Cap.Channel_ID;
+		priv->NCSI_Request.Channel_ID = Combined_Channel_ID;
+		priv->NCSI_Request.Payload_Length = (8 << 8);
+		memcpy ((unsigned char *)skb->data, &priv->NCSI_Request, 30);
+		priv->NCSI_Request.Payload_Length = 8;
+		for (i = 0; i < 6; i++) {
+			priv->Payload_Data[i] = cur_addr->dmi_addr[i];
+		}
+		priv->Payload_Data[6] = 2; //MAC Address Num = 1 --> address filter 1, fixed in sample code
+		priv->Payload_Data[7] = MULTICAST_ADDRESS + 0 + ENABLE_MAC_ADDRESS_FILTER; //AT + Reserved + E
+		copy_data (dev, skb, priv->NCSI_Request.Payload_Length);
+		skb->len =  30 + priv->NCSI_Request.Payload_Length + 4;
+		ftgmac100_wait_to_send_packet(skb, dev);
+	}
+#endif
+	for (cur_addr = addrs ; cur_addr!=NULL ; cur_addr = cur_addr->next )
+	{
+		/* make sure this is a multicast address - shouldn't this be a given if we have it here ? */
+		if ( !( *cur_addr->dmi_addr & 1 ) )
+		{
+			continue;
+		}
+#if 1
+//A0, A1
+			crc_val = crc32( cur_addr->dmi_addr, 5 );
+			crc_val = (~(crc_val>>2)) & 0x3f;
+			if (crc_val >= 32)
+			{
+				outl(inl(ioaddr+MAHT1_REG) | (1UL<<(crc_val-32)), ioaddr+MAHT1_REG);
+				priv->GigaBit_MAHT1 = inl (ioaddr + MAHT1_REG);
+			}
+			else
+			{
+				outl(inl(ioaddr+MAHT0_REG) | (1UL<<crc_val), ioaddr+MAHT0_REG);
+				priv->GigaBit_MAHT0 = inl (ioaddr + MAHT0_REG);
+			}
+//10/100M
+			crc_val = crc32( cur_addr->dmi_addr, 6 );
+			crc_val = (~(crc_val>>2)) & 0x3f;
+			if (crc_val >= 32)
+			{
+				outl(inl(ioaddr+MAHT1_REG) | (1UL<<(crc_val-32)), ioaddr+MAHT1_REG);
+				priv->Not_GigaBit_MAHT1 = inl (ioaddr + MAHT1_REG);
+			}
+			else
+			{
+				outl(inl(ioaddr+MAHT0_REG) | (1UL<<crc_val), ioaddr+MAHT0_REG);
+				priv->Not_GigaBit_MAHT0 = inl (ioaddr + MAHT0_REG);
+			}
+#else
+//A2
+			crc_val = crc32( cur_addr->dmi_addr, 6 );
+			crc_val = (~(crc_val>>2)) & 0x3f;
+			if (crc_val >= 32)
+			{
+				outl(inl(ioaddr+MAHT1_REG) | (1UL<<(crc_val-32)), ioaddr+MAHT1_REG);
+				priv->Not_GigaBit_MAHT1 = inl (ioaddr + MAHT1_REG);
+				priv->GigaBit_MAHT1 = inl (ioaddr + MAHT1_REG);
+			}
+			else
+			{
+				outl(inl(ioaddr+MAHT0_REG) | (1UL<<crc_val), ioaddr+MAHT0_REG);
+				priv->Not_GigaBit_MAHT0 = inl (ioaddr + MAHT0_REG);
+				priv->GigaBit_MAHT0 = inl (ioaddr + MAHT0_REG);
+			}
+#endif
+	}
+}
+
+/*-----------------------------------------------------------
+ . ftgmac100_set_multicast_list
+ .
+ . This routine will, depending on the values passed to it,
+ . either make it accept multicast packets, go into
+ . promiscuous mode ( for TCPDUMP and cousins ) or accept
+ . a select set of multicast packets
+*/
+static void ftgmac100_set_multicast_list(struct net_device *dev)
+{
+	unsigned int ioaddr = dev->base_addr;
+	struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+
+	PRINTK2("%s:ftgmac100_set_multicast_list\n", dev->name);
+
+	if (dev->flags & IFF_PROMISC)
+		priv->maccr_val |= RX_ALLADR_bit;
+	else
+		priv->maccr_val &= ~RX_ALLADR_bit;
+
+	if (dev->flags & IFF_ALLMULTI)
+		priv->maccr_val |= RX_MULTIPKT_bit;
+	else
+		priv->maccr_val &= ~RX_MULTIPKT_bit;
+
+	if (dev->mc_count)
+	{
+//		PRINTK("set multicast\n");
+		priv->maccr_val |= RX_HT_EN_bit;
+		ftgmac100_setmulticast( dev, dev->mc_count, dev->mc_list );
+	}
+	else
+	{
+		priv->maccr_val &= ~RX_HT_EN_bit;
+	}
+
+	outl( priv->maccr_val, ioaddr + MACCR_REG );
+
+}
+#endif
+
+static int ast_gmac_stop(struct net_device *dev)
+{
+	struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+
+	netif_stop_queue(dev);
+
+	/* clear everything */
+	ftgmac100_shutdown(dev->base_addr);
+	free_irq(dev->irq, dev);
+
+	if (priv->timer.function != NULL) {
+	    del_timer_sync(&priv->timer);
+	}
+
+	if (priv->rx_descs)
+			dma_free_coherent( NULL, sizeof(RX_DESC)*RXDES_NUM, (void*)priv->rx_descs, (dma_addr_t)priv->rx_descs_dma );
+	if (priv->tx_descs)
+			dma_free_coherent( NULL, sizeof(TX_DESC)*TXDES_NUM, (void*)priv->tx_descs, (dma_addr_t)priv->tx_descs_dma );
+	if (priv->tx_buf)
+			dma_free_coherent( NULL, TX_BUF_SIZE*TXDES_NUM, (void*)priv->tx_buf, (dma_addr_t)priv->tx_buf_dma );
+	priv->rx_descs = NULL; priv->rx_descs_dma = 0;
+	priv->tx_descs = NULL; priv->tx_descs_dma = 0;
+	priv->tx_buf   = NULL; priv->tx_buf_dma   = 0;
+	
+
+	return 0;
+}
+
+static struct proc_dir_entry *proc_ftgmac100;
+
+static int ftgmac100_read_proc(char *page, char **start,  off_t off, int count, int *eof, void *data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct ftgmac100_priv *priv 	= (struct ftgmac100_priv *)dev->priv;
+	int num;
+	int i;
+
+	num = sprintf(page, "priv->rx_idx = %d\n", priv->rx_idx);
+	for (i=0; i<RXDES_NUM; ++i)
+	{
+		num += sprintf(page + num, "[%d].RXDMA_OWN = %d\n", i, priv->rx_descs[i].RXPKT_RDY);
+	}
+	return num;
+}
+
+static int ftgmac100_open(struct net_device *netdev)
+{
+	struct ftgmac100_priv *priv = netdev_priv(netdev);
+	int err;
+
+	DO_PRINT("%s:ftgmac100_open\n", netdev->name);
+
+	priv->maccr_val = (CRC_APD_bit | RXMAC_EN_bit | TXMAC_EN_bit  | RXDMA_EN_bit
+			 | TXDMA_EN_bit | CRC_CHK_bit | RX_BROADPKT_bit | SPEED_100_bit | FULLDUP_bit);
+
+	ftgmac100_ringbuf_alloc(priv);
+
+
+	/* Grab the IRQ next.  Beyond this, we will free the IRQ. */
+	err = request_irq(netdev->irq, (void *)&ftgmac100_interrupt,
+			     IRQF_DISABLED, netdev->name, netdev);
+	if (err)
+	{
+		DO_PRINT("%s: unable to get IRQ %d (retval=%d).\n",
+			 netdev->name, netdev->irq, err);
+		kfree(netdev->priv);
+		netdev->priv = NULL;
+		return err;
+	}
+
+
+	netif_start_queue(netdev);
+
+	/* reset the hardware */
+	ftgmac100_reset(netdev);
+	ftgmac100_enable(netdev);
+
+	if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) || 
+	    ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL) ||
+        (priv->ids.miiPhyId == PHYID_BCM54612E)) { 
+
+        init_timer(&priv->timer);
+	    priv->timer.data = (unsigned long)netdev;
+	    priv->timer.function = aspeed_mac_timer;
+	    priv->timer.expires = jiffies + 1 * HZ;
+	    add_timer (&priv->timer);
+	}
+
+	/* Configure the PHY */
+	ftgmac100_phy_configure(netdev);
+
+	netif_start_queue(netdev);
+	return 0;
+}
+
+static int __init ast_gmac_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct net_device *netdev;
+	struct ftgmac100_priv *priv;
+	 struct ftgmac100_eth_data *ast_eth_data = pdev->dev.platform_data;;
+	int err;
+
+	if (!pdev)
+		return -ENODEV;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENXIO;
+
+	/* setup net_device */
+	netdev = alloc_etherdev(sizeof(*priv));
+	if (!netdev) {
+		err = -ENOMEM;
+		goto err_alloc_etherdev;
+	}
+
+	netdev->irq = platform_get_irq(pdev, 0);
+	if (netdev->irq < 0) {
+		err = -ENXIO;
+		goto err_netdev;
+	}
+
+	SET_NETDEV_DEV(netdev, &pdev->dev);
+
+
+//	SET_ETHTOOL_OPS(netdev, &ftgmac100_ethtool_ops);
+	
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30))
+	netdev->netdev_ops 			= &ftgmac100_netdev_ops;
+#else
+	printk("ast_gmac_probe 5\n");
+
+	ether_setup(netdev);
+
+	netdev->open				= ftgmac100_open;
+	netdev->stop				= ast_gmac_stop;
+	netdev->hard_start_xmit 	= ftgmac100_wait_to_send_packet;
+	netdev->tx_timeout 			= ftgmac100_timeout;
+	netdev->get_stats 			= ftgmac100_query_statistics;
+//#ifdef	HAVE_MULTICAST
+#if 0
+	netdev->set_multicast_list 	= &ftgmac100_set_multicast_list;
+#endif
+
+#endif
+	
+
+#ifdef CONFIG_AST_NPAI
+//	netdev->features = NETIF_F_GRO;
+//	netdev->features = NETIF_F_IP_CSUM | NETIF_F_GRO;
+#endif
+
+	platform_set_drvdata(pdev, netdev);
+
+	/* setup private data */
+	priv = netdev_priv(netdev);
+	priv->netdev = netdev;
+	priv->dev = &pdev->dev;
+	
+
+	priv->ids.macId = pdev->id;
+	
+	priv->NCSI_support = ast_eth_data->NCSI_support;
+	priv->INTEL_NCSI_EVA_support= ast_eth_data->INTEL_NCSI_EVA_support;	
+	spin_lock_init(&priv->tx_lock);
+
+#if 0
+	/* initialize NAPI */
+	netif_napi_add(netdev, &priv->napi, ftgmac100_poll, 64);
+#endif
+	/* map io memory */
+	res = request_mem_region(res->start, resource_size(res),
+					   dev_name(&pdev->dev));
+	if (!res) {
+		dev_err(&pdev->dev, "Could not reserve memory region\n");
+		err = -ENOMEM;
+		goto err_req_mem;
+	}
+
+	netdev->base_addr = (u32)ioremap(res->start, resource_size(res));
+
+	if (!netdev->base_addr) {
+		dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n");
+		err = -EIO;
+		goto err_ioremap;
+	}
+
+//	priv->irq = irq;
+#if 0//CONFIG_AST_MDIO
+	/* initialize mdio bus */
+	priv->mii_bus = mdiobus_alloc();
+	if (!priv->mii_bus) {
+		err = -EIO;
+		goto err_alloc_mdiobus;
+	}
+
+	priv->mii_bus->name = "ftgmac100_mdio";
+	snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "ftgmac100_mii.%d",pdev->id);
+
+	priv->mii_bus->priv = netdev;
+	priv->mii_bus->read = ftgmac100_mdiobus_read;
+	priv->mii_bus->write = ftgmac100_mdiobus_write;
+	priv->mii_bus->reset = ftgmac100_mdiobus_reset;
+	priv->mii_bus->irq = priv->phy_irq;
+
+	for (i = 0; i < PHY_MAX_ADDR; i++)
+		priv->mii_bus->irq[i] = PHY_POLL;
+
+	err = mdiobus_register(priv->mii_bus);
+	if (err) {
+		dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
+		goto err_register_mdiobus;
+	}
+
+	err = ftgmac100_mii_probe(priv);
+	if (err) {
+		dev_err(&pdev->dev, "MII Probe failed!\n");
+		goto err_mii_probe;
+	}
+#endif
+	/* register network device */
+	err = register_netdev(netdev);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to register netdev\n");
+		goto err_alloc_mdiobus;
+	}
+
+//	printk("irq %d, mapped at %x\n", netdev->irq, (u32)netdev->base_addr);
+
+	if (!is_valid_ether_addr(netdev->dev_addr)) {
+		random_ether_addr(netdev->dev_addr);
+		printk("generated random MAC address %pM\n",
+				netdev->dev_addr);
+	}
+#if 0
+	if ((proc_ftgmac100 = create_proc_entry( dev->name, 0, 0 )))
+	{
+		proc_ftgmac100->read_proc = ftgmac100_read_proc;
+		proc_ftgmac100->data = dev;
+		proc_ftgmac100->owner = THIS_MODULE;
+	}
+#endif
+	return 0;
+
+//err_register_netdev:
+//	phy_disconnect(priv->phydev);
+//err_mii_probe:
+//	mdiobus_unregister(priv->mii_bus);
+//err_register_mdiobus:
+//	mdiobus_free(priv->mii_bus);
+err_alloc_mdiobus:
+	iounmap((void __iomem *)netdev->base_addr);
+err_ioremap:
+	release_resource(res);
+err_req_mem:
+//	netif_napi_del(&priv->napi);
+	platform_set_drvdata(pdev, NULL);
+err_netdev:	
+	free_netdev(netdev);
+err_alloc_etherdev:
+	return err;
+
+}
+
+static int __devexit ast_gmac_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+//	struct ftgmac100_priv *priv = netdev_priv(dev);
+
+//	remove_proc_entry(dev->name, 0);
+
+	unregister_netdev(dev);
+
+#ifdef CONFIG_MII_PHY
+	phy_disconnect(priv->phydev);
+	mdiobus_unregister(priv->mii_bus);
+	mdiobus_free(priv->mii_bus);
+#endif
+
+	iounmap((void __iomem *)dev->base_addr);
+
+#ifdef CONFIG_AST_NPAI
+	netif_napi_del(&priv->napi);
+#endif
+
+	platform_set_drvdata(pdev, NULL);
+	free_netdev(dev);
+	return 0;
+}
+
+static struct platform_driver ast_gmac_driver = {
+	.remove		= __devexit_p(ast_gmac_remove),
+	.driver		= {
+		.name	= "ast_gmac",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init ast_gmac_init(void)
+{
+	return platform_driver_probe(&ast_gmac_driver, ast_gmac_probe);
+}
+
+static void __exit ast_gmac_exit(void)
+{
+	platform_driver_unregister(&ast_gmac_driver);
+}
+
+module_init(ast_gmac_init)
+module_exit(ast_gmac_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("ASPEED Technology Inc.");
+MODULE_DESCRIPTION("NIC driver for AST Series");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ftgmac100_26.h b/drivers/net/ftgmac100_26.h
new file mode 100644
index 0000000..f145b05
--- /dev/null
+++ b/drivers/net/ftgmac100_26.h
@@ -0,0 +1,580 @@
+/********************************************************************************
+* File Name     : ftgmac100_26.h
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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 FTMAC100_H
+#define FTMAC100_H
+
+#define HAVE_MULTICAST
+
+#define ISR_REG				0x00				// interrups status register
+#define IER_REG				0x04				// interrupt maks register
+#define MAC_MADR_REG		0x08				// MAC address (Most significant)
+#define MAC_LADR_REG		0x0c				// MAC address (Least significant)
+
+#define MAHT0_REG			0x10				// Multicast Address Hash Table 0 register
+#define MAHT1_REG			0x14				// Multicast Address Hash Table 1 register
+#define TXPD_REG			0x18				// Transmit Poll Demand register
+#define RXPD_REG			0x1c				// Receive Poll Demand register
+#define TXR_BADR_REG		0x20				// Transmit Ring Base Address register
+#define RXR_BADR_REG		0x24				// Receive Ring Base Address register
+
+#define HPTXPD_REG			0x28	//
+#define HPTXR_BADR_REG		0x2c	//
+
+#define ITC_REG				0x30				// interrupt timer control register
+#define APTC_REG			0x34				// Automatic Polling Timer control register
+#define DBLAC_REG			0x38				// DMA Burst Length and Arbitration control register
+
+#define DMAFIFOS_REG		0x3c	//
+#define FEAR_REG			0x44	//
+#define TPAFCR_REG			0x48	//
+#define RBSR_REG			0x4c	//for NC Body
+#define MACCR_REG			0x50				// MAC control register
+#define MACSR_REG			0x54				// MAC status register
+#define PHYCR_REG			0x60				// PHY control register
+#define PHYDATA_REG			0x64				// PHY Write Data register
+#define FCR_REG				0x68				// Flow Control register
+#define BPR_REG				0x6c				// back pressure register
+#define WOLCR_REG			0x70				// Wake-On-Lan control register
+#define WOLSR_REG			0x74				// Wake-On-Lan status register
+#define WFCRC_REG			0x78				// Wake-up Frame CRC register
+#define WFBM1_REG			0x80				// wake-up frame byte mask 1st double word register
+#define WFBM2_REG			0x84				// wake-up frame byte mask 2nd double word register
+#define WFBM3_REG			0x88				// wake-up frame byte mask 3rd double word register
+#define WFBM4_REG			0x8c				// wake-up frame byte mask 4th double word register
+
+#define NPTXR_PTR_REG		0x90	//
+#define HPTXR_PTR_REG		0x94	//
+#define RXR_PTR_REG			0x98	//
+
+
+// --------------------------------------------------------------------
+//		ISR_REG ¤Î IMR_REG 
+// --------------------------------------------------------------------
+#define HPTXBUF_UNAVA_bit	(1UL<<10)
+#define PHYSTS_CHG_bit		(1UL<<9)
+#define AHB_ERR_bit			(1UL<<8)
+#define TPKT_LOST_bit		(1UL<<7)
+#define NPTXBUF_UNAVA_bit	(1UL<<6)
+#define TPKT2F_bit			(1UL<<5)
+#define TPKT2E_bit			(1UL<<4)
+#define RPKT_LOST_bit		(1UL<<3)
+#define RXBUF_UNAVA_bit		(1UL<<2)
+#define RPKT2F_bit			(1UL<<1)
+#define RPKT2B_bit			(1UL<<0)
+
+
+// --------------------------------------------------------------------
+//	APTC_REG 
+// --------------------------------------------------------------------
+
+
+typedef struct
+{
+	u32 RXPOLL_CNT:4;
+	u32 RXPOLL_TIME_SEL:1;
+	u32 Reserved1:3;
+	u32 TXPOLL_CNT:4;
+	u32 TXPOLL_TIME_SEL:1;
+	u32 Reserved2:19;
+}FTGMAC100_APTCR_Status;
+
+// --------------------------------------------------------------------
+//		PHYCR_REG
+// --------------------------------------------------------------------
+#define PHY_RE_AUTO_bit			(1UL<<9)
+#define PHY_READ_bit			(1UL<<26)
+#define PHY_WRITE_bit			(1UL<<27)
+// --------------------------------------------------------------------
+//		PHYCR_REG 
+// --------------------------------------------------------------------
+#define PHY_AUTO_OK_bit			(1UL<<5)
+// --------------------------------------------------------------------
+//		PHY INT_STAT_REG 
+// --------------------------------------------------------------------
+#define PHY_SPEED_CHG_bit		(1UL<<14)
+#define PHY_DUPLEX_CHG_bit		(1UL<<13)
+#define PHY_LINK_CHG_bit		(1UL<<10)
+#define PHY_AUTO_COMP_bit		(1UL<<11)
+// --------------------------------------------------------------------
+//		PHY SPE_STAT_REG 
+// --------------------------------------------------------------------
+#define PHY_RESOLVED_bit		(1UL<<11)
+#define PHY_SPEED_mask			0xC000
+#define PHY_SPEED_10M			0x0
+#define PHY_SPEED_100M			0x1
+#define PHY_SPEED_1G			0x2
+#define PHY_DUPLEX_mask                 0x2000
+//#define PHY_FULLDUPLEX                  0x1
+#define PHY_SPEED_DUPLEX_MASK           0x01E0
+#define PHY_100M_DUPLEX                 0x0100
+#define PHY_100M_HALF                   0x0080
+#define PHY_10M_DUPLEX                  0x0040
+#define PHY_10M_HALF                    0x0020
+#define LINK_STATUS                     0x04
+
+
+// --------------------------------------------------------------------
+//		MACCR_REG
+// --------------------------------------------------------------------
+
+#define SW_RST_bit			(1UL<<31)				// software reset/
+#define DIRPATH_bit			(1UL<<21)
+#define RX_IPCS_FAIL_bit	(1UL<<20)	//
+#define SPEED_100_bit   	        (1UL<<19)	//
+#define RX_UDPCS_FAIL_bit	(1UL<<18)	//
+#define RX_BROADPKT_bit		(1UL<<17)				// Receiving broadcast packet
+#define RX_MULTIPKT_bit		(1UL<<16)				// receiving multicast packet
+#define RX_HT_EN_bit		(1UL<<15)
+#define RX_ALLADR_bit		(1UL<<14)				// not check incoming packet's destination address
+#define JUMBO_LF_bit		(1UL<<13)	//
+#define RX_RUNT_bit			(1UL<<12)				// Store incoming packet even its length is les than 64 byte
+#define CRC_CHK_bit			(1UL<<11)	//
+#define CRC_APD_bit			(1UL<<10)				// append crc to transmit packet
+#define GMAC_MODE_bit		(1UL<<9)	//
+#define FULLDUP_bit			(1UL<<8)				// full duplex
+#define ENRX_IN_HALFTX_bit	(1UL<<7)	//
+#define LOOP_EN_bit			(1UL<<6)				// Internal loop-back
+#define HPTXR_EN_bit		(1UL<<5)	//
+#define REMOVE_VLAN_bit		(1UL<<4)	//
+//#define MDC_SEL_bit		(1UL<<13)				// set MDC as TX_CK/10
+//#define RX_FTL_bit		(1UL<<11)				// Store incoming packet even its length is great than 1518 byte
+#define RXMAC_EN_bit		(1UL<<3)				// receiver enable
+#define TXMAC_EN_bit		(1UL<<2)				// transmitter enable
+#define RXDMA_EN_bit		(1UL<<1)				// enable DMA receiving channel
+#define TXDMA_EN_bit		(1UL<<0)				// enable DMA transmitting channel
+
+
+// --------------------------------------------------------------------
+//		SCU_REG
+// --------------------------------------------------------------------
+#define  SCU_PROTECT_KEY_REG                0x0
+#define  SCU_PROT_KEY_MAGIC                 0x1688a8a8
+#define  SCU_RESET_CONTROL_REG              0x04
+#define  SCU_RESET_MAC1                     (1u << 11)
+#define  SCU_RESET_MAC2                     (1u << 12)
+
+#define  SCU_HARDWARE_TRAPPING_REG          0x70
+#define  SCU_HT_MAC_INTF_LSBIT              6
+#define  SCU_HT_MAC_INTERFACE               (0x7u << SCU_HT_MAC_INTF_LSBIT)
+#define  MAC_INTF_SINGLE_PORT_MODES         (1u<<0/*GMII*/ | 1u<<3/*MII_ONLY*/ | 1u<<4/*RMII_ONLY*/)
+#define  SCU_HT_MAC_GMII                    0x0u
+// MII and MII mode
+#define  SCU_HT_MAC_MII_MII                 0x1u
+#define  SCU_HT_MAC_MII_ONLY                0x3u
+#define  SCU_HT_MAC_RMII_ONLY               0x4u
+
+/*
+SCU88 D[31]: MAC1 MDIO
+SCU88 D[30]: MAC1 MDC
+SCU90 D[2]:  MAC2 MDC/MDIO
+SCU80 D[0]:  MAC1 Link
+SCU80 D[1]:  MAC2 Link
+*/
+#define  SCU_MULTIFUNCTION_PIN_REG          0x74
+#define  SCU_MULTIFUNCTION_PIN_CTL1_REG     0x80
+#define  SCU_MULTIFUNCTION_PIN_CTL3_REG     0x88
+#define  SCU_MULTIFUNCTION_PIN_CTL5_REG     0x90
+#define  SCU_MFP_MAC2_PHYLINK               (1u << 1)
+#define  SCU_MFP_MAC1_PHYLINK               (1u << 0)
+#define  SCU_MFP_MAC2_MII_INTF              (1u << 21)
+#define  SCU_MFP_MAC2_MDC_MDIO              (1u << 2)
+#define  SCU_MFP_MAC1_MDIO                  (1u << 31)
+#define  SCU_MFP_MAC1_MDC                   (1u << 30)
+#define  SCU_SILICON_REVISION_REG           0x7C
+#define  SCU_SCRATCH_REG	            0x40
+
+
+
+// --------------------------------------------------------------------
+//		NCSI
+// --------------------------------------------------------------------
+
+//NCSI define & structure
+//NC-SI Command Packet
+typedef struct {
+//Ethernet Header
+    unsigned char  DA[6];
+    unsigned char  SA[6];
+    unsigned short EtherType;						//DMTF NC-SI
+//NC-SI Control Packet
+    unsigned char  MC_ID;						//Management Controller should set this field to 0x00
+    unsigned char  Header_Revision;					//For NC-SI 1.0 spec, this field has to set 0x01
+    unsigned char  Reserved_1;						//Reserved has to set to 0x00
+    unsigned char  IID;							//Instance ID
+    unsigned char  Command;
+    unsigned char  Channel_ID;
+    unsigned short Payload_Length;					//Payload Length = 12 bits, 4 bits are reserved
+    unsigned long  Reserved_2;
+    unsigned long  Reserved_3;
+}  NCSI_Command_Packet;
+
+//Command and Response Type
+#define	CLEAR_INITIAL_STATE			0x00			//M
+#define	SELECT_PACKAGE				0x01			//M
+#define	DESELECT_PACKAGE			0x02			//M
+#define	ENABLE_CHANNEL				0x03			//M
+#define	DISABLE_CHANNEL				0x04			//M
+#define	RESET_CHANNEL				0x05			//M
+#define	ENABLE_CHANNEL_NETWORK_TX		0x06			//M
+#define	DISABLE_CHANNEL_NETWORK_TX		0x07			//M
+#define	AEN_ENABLE				0x08
+#define	SET_LINK				0x09			//M
+#define	GET_LINK_STATUS				0x0A			//M
+#define	SET_VLAN_FILTER				0x0B			//M
+#define	ENABLE_VLAN				0x0C			//M
+#define	DISABLE_VLAN				0x0D			//M
+#define	SET_MAC_ADDRESS				0x0E			//M
+#define	ENABLE_BROADCAST_FILTERING		0x10			//M
+#define	DISABLE_BROADCAST_FILTERING		0x11			//M
+#define	ENABLE_GLOBAL_MULTICAST_FILTERING	0x12
+#define	DISABLE_GLOBAL_MULTICAST_FILTERING	0x13
+#define	SET_NCSI_FLOW_CONTROL			0x14
+#define	GET_VERSION_ID				0x15			//M
+#define	GET_CAPABILITIES			0x16			//M
+#define	GET_PARAMETERS				0x17			//M
+#define	GET_CONTROLLER_PACKET_STATISTICS	0x18
+#define	GET_NCSI_STATISTICS			0x19
+#define	GET_NCSI_PASS_THROUGH_STATISTICS	0x1A
+
+//NC-SI Response Packet
+typedef struct {
+    unsigned char  DA[6];
+    unsigned char  SA[6];
+    unsigned short EtherType;						//DMTF NC-SI
+//NC-SI Control Packet
+    unsigned char  MC_ID;						//Management Controller should set this field to 0x00
+    unsigned char  Header_Revision;					//For NC-SI 1.0 spec, this field has to set 0x01
+    unsigned char  Reserved_1;						//Reserved has to set to 0x00
+    unsigned char  IID;							//Instance ID
+    unsigned char  Command;
+    unsigned char  Channel_ID;
+    unsigned short Payload_Length;					//Payload Length = 12 bits, 4 bits are reserved
+    unsigned short  Reserved_2;
+    unsigned short  Reserved_3;
+    unsigned short  Reserved_4;
+    unsigned short  Reserved_5;
+    unsigned short  Response_Code;
+    unsigned short  Reason_Code;
+    unsigned char   Payload_Data[64];
+}  NCSI_Response_Packet;
+
+//Standard Response Code
+#define	COMMAND_COMPLETED			0x00
+#define	COMMAND_FAILED				0x01
+#define	COMMAND_UNAVAILABLE			0x02
+#define	COMMAND_UNSUPPORTED			0x03
+
+//Standard Reason Code
+#define	NO_ERROR				0x0000
+#define	INTERFACE_INITIALIZATION_REQUIRED	0x0001
+#define	PARAMETER_IS_INVALID			0x0002
+#define	CHANNEL_NOT_READY			0x0003
+#define	PACKAGE_NOT_READY			0x0004
+#define	INVALID_PAYLOAD_LENGTH			0x0005
+#define	UNKNOWN_COMMAND_TYPE			0x7FFF
+
+
+struct AEN_Packet {
+//Ethernet Header
+    unsigned char  DA[6];
+    unsigned char  SA[6];						//Network Controller SA = FF:FF:FF:FF:FF:FF
+    unsigned short EtherType;						//DMTF NC-SI
+//AEN Packet Format
+    unsigned char  MC_ID;						//Network Controller should set this field to 0x00
+    unsigned char  Header_Revision;					//For NC-SI 1.0 spec, this field has to set 0x01
+    unsigned char  Reserved_1;						//Reserved has to set to 0x00
+//    unsigned char  IID = 0x00;						//Instance ID = 0 in Network Controller
+//    unsigned char  Command = 0xFF;					//AEN = 0xFF
+    unsigned char  Channel_ID;
+//    unsigned short Payload_Length = 0x04;				//Payload Length = 4 in Network Controller AEN Packet
+    unsigned long  Reserved_2;
+    unsigned long  Reserved_3;
+    unsigned char  AEN_Type;
+//    unsigned char  Reserved_4[3] = {0x00, 0x00, 0x00};
+    unsigned long  Optional_AEN_Data;
+    unsigned long  Payload_Checksum;
+};
+
+//AEN Type
+#define	LINK_STATUS_CHANGE			0x0
+#define	CONFIGURATION_REQUIRED			0x1
+#define	HOST_NC_DRIVER_STATUS_CHANGE		0x2
+
+typedef struct {
+	unsigned char Package_ID;
+	unsigned char Channel_ID;
+	unsigned long Capabilities_Flags;
+	unsigned long Broadcast_Packet_Filter_Capabilities;
+	unsigned long Multicast_Packet_Filter_Capabilities;
+	unsigned long Buffering_Capabilities;
+	unsigned long AEN_Control_Support;
+} NCSI_Capability;
+NCSI_Capability NCSI_Cap;
+
+//SET_MAC_ADDRESS
+#define UNICAST		(0x00 << 5)
+#define MULTICAST_ADDRESS	(0x01 << 5)
+#define DISABLE_MAC_ADDRESS_FILTER	0x00
+#define ENABLE_MAC_ADDRESS_FILTER	0x01
+
+//GET_LINK_STATUS
+#define LINK_DOWN	0
+#define LINK_UP		1
+
+#define NCSI_LOOP   1500000
+#define RETRY_COUNT     1
+
+#define NCSI_HEADER	0xF888		//Reversed because of 0x88 is low byte, 0xF8 is high byte in memory
+
+// --------------------------------------------------------------------
+//		Receive Ring descriptor structure
+// --------------------------------------------------------------------
+
+typedef struct
+{
+	// RXDES0
+	u32 VDBC:14;//0~10
+	u32 Reserved1:1;          //11~15
+	u32 Reserved3:1;
+	u32 MULTICAST:1;          //16
+	u32 BROADCAST:1;          //17
+	u32 RX_ERR:1;             //18
+	u32 CRC_ERR:1;            //19
+	u32 FTL:1;
+	u32 RUNT:1;
+	u32 RX_ODD_NB:1;
+	u32 FIFO_FULL:1;
+	u32 PAUSE_OPCODE:1;
+	u32 PAUSE_FRAME:1;
+	u32 Reserved2:2;
+	u32 LRS:1;
+	u32 FRS:1;
+	u32 EDORR:1;
+	u32 RXPKT_RDY:1;		// 1 ==> owned by FTMAC100, 0 ==> owned by software
+	
+	// RXDES1
+	u32 VLAN_TAGC:16;
+	u32 Reserved4:4;
+	u32 PROTL_TYPE:2;
+	u32 LLC_PKT:1;
+	u32 DF:1;
+	u32 VLAN_AVA:1;	
+	u32 TCPCS_FAIL:1;
+	u32 UDPCS_FAIL:1;
+	u32 IPCS_FAIL:1;
+	u32 Reserved5:4;
+	
+	// RXDES2
+	u32 Reserved6:32;
+	
+	// RXDES3
+	u32 RXBUF_BADR;
+				
+	u32 VIR_RXBUF_BADR;			// not defined, the virtual address of receive buffer is placed here
+	
+	u32 RESERVED; 
+	u32 RESERVED1; 
+	u32 RESERVED2;	
+}RX_DESC;
+
+
+typedef struct
+{
+	// TXDES0
+	u32 TXBUF_Size:14;
+	u32 Reserved1:1;
+	u32 Reserved2:1;
+	u32 Reserved3:3;
+	u32 CRC_ERR:1;
+	u32 Reserved4:8;
+	u32 LTS:1;
+	u32 FTS:1;
+	u32 EDOTR:1;
+	u32 TXDMA_OWN:1;
+	
+	// TXDES1
+	u32 VLAN_TAGC:16;
+	u32 INS_VLAN:1;
+	u32 TCPCS_EN:1;
+	u32 UDPCS_EN:1;
+	u32 IPCS_EN:1;
+	u32 Reserved5:2;
+	u32 LLC_PKT:1;
+	u32 Reserved6:7;
+	u32 TX2FIC:1;
+	u32 TXIC:1;	
+	
+	// TXDES2
+	u32 Reserved7:32;
+
+	// TXDES3
+	u32 TXBUF_BADR;
+
+	u32 VIR_TXBUF_BADR;			// Reserve, the virtual address of transmit buffer is placed here
+
+	u32 RESERVED;
+	u32 RESERVED1; 
+	u32 RESERVED2; 
+
+}TX_DESC;
+
+
+
+// waiting to do:
+#define	TXPOLL_CNT			8
+#define RXPOLL_CNT			0
+
+#define TX_OWNBY_SOFTWARE		0
+#define TX_OWNBY_FTGMAC100		1
+
+
+#define RX_OWNBY_SOFTWARE		1
+#define RX_OWNBY_FTGMAC100		0
+
+// --------------------------------------------------------------------
+//		driver related definition
+// --------------------------------------------------------------------
+
+
+//#define RXDES_NUM			64//64 // we defined 32 descriptor for OTG issue 
+#define RXDES_NUM			32
+
+#define RX_BUF_SIZE			1536
+
+#define TXDES_NUM			32
+#define TX_BUF_SIZE			1536
+
+#define PHYID_VENDOR_MASK               0xfffffc00
+#define PHYID_VENDOR_MODEL_MASK         0xfffffff0
+#define PHYID_MODEL_MASK                0x000003f0
+#define PHYID_REVISION_MASK             0x0000000f
+#define PHYID_VENDOR_MARVELL            0x01410c00
+#define PHYID_VENDOR_BROADCOM           0x00406000
+#define PHYID_VENDOR_REALTEK            0x001cc800
+
+#define PHYID_BCM5221A4                 0x004061e4
+//#define PHYID_RTL8201EL                 0x001cc815
+#define PHYID_RTL8201EL					0x001cc810
+#define PHYID_RTL8201F                  0x001cc816
+#define PHYID_RTL8211                   0x001cc910
+#define PHYID_RTL8211E                  0x001cc915
+#define PHYID_BCM54612E             	0x03625E6A
+
+
+/* store this information for the driver.. */
+
+struct AstMacHwConfig {
+    unsigned char phyAddr;	// See IP_phy_addr[] encoding
+    unsigned char macId;
+    unsigned char isRevA0;
+    unsigned char isRevA2;
+    unsigned char pad[1];
+    unsigned int  miiPhyId;
+};
+
+struct ftgmac100_priv {
+
+ 	// these are things that the kernel wants me to keep, so users
+	// can find out semi-useless statistics of how well the card is
+	// performing
+	struct net_device_stats stats;
+
+	struct AstMacHwConfig ids;
+
+	struct net_device *netdev;
+	struct device *dev;
+
+	// Set to true during the auto-negotiation sequence
+	int	autoneg_active;
+
+	// Last contents of PHY Register 18
+	u32		lastPhy18;
+
+	spinlock_t tx_lock;
+
+	//RX ..
+	volatile RX_DESC *rx_descs;			// receive ring base address
+	struct sk_buff *rx_skbuff[RXDES_NUM];
+	u32		rx_descs_dma;				// receive ring physical base address
+	int		rx_idx;						// receive descriptor
+
+	//TX ..
+	volatile TX_DESC *tx_descs;
+	u32		tx_descs_dma;
+	char	*tx_buf;
+	int		tx_buf_dma;
+	int		tx_idx;
+	int		old_tx;
+	struct sk_buff *tx_skbuff[TXDES_NUM];
+	
+	int     maccr_val;
+        struct timer_list    timer;
+	u32		GigaBit_MAHT0;
+	u32		GigaBit_MAHT1;
+	u32		Not_GigaBit_MAHT0;
+	u32		Not_GigaBit_MAHT1;
+	NCSI_Command_Packet NCSI_Request;
+	NCSI_Response_Packet NCSI_Respond;
+	NCSI_Capability NCSI_Cap;
+	unsigned int 	InstanceID;
+	unsigned int 	Retry;
+	unsigned char	Payload_Data[16];
+	unsigned char	Payload_Pad[4];
+	unsigned long	Payload_Checksum;
+	int		tx_free;
+	unsigned long	NCSI_support;
+	unsigned long	INTEL_NCSI_EVA_support;
+};
+
+
+#define FTGMAC100_STROBE_TIME			(10*HZ)
+///#define FTMAC100_STROBE_TIME			1
+
+//I2C define for EEPROM
+#define    AC_TIMING        0x77743335
+#define    ALL_CLEAR        0xFFFFFFFF
+#define    MASTER_ENABLE    0x01
+#define    SLAVE_ENABLE     0x02
+#define    LOOP_COUNT       0x100000
+
+
+#define    I2C_BASE                         0x1e78A000
+#define    I2C_FUNCTION_CONTROL_REGISTER    0x00
+#define    I2C_AC_TIMING_REGISTER_1         0x04
+#define    I2C_AC_TIMING_REGISTER_2         0x08
+#define    I2C_INTERRUPT_CONTROL_REGISTER   0x0C
+#define    I2C_INTERRUPT_STATUS_REGISTER    0x10
+#define    I2C_COMMAND_REGISTER             0x14
+#define    I2C_BYTE_BUFFER_REGISTER         0x20
+
+
+#define    MASTER_START_COMMAND    (1 << 0)
+#define    MASTER_TX_COMMAND       (1 << 1)
+#define    MASTER_RX_COMMAND       (1 << 3)
+#define    RX_COMMAND_LIST         (1 << 4)
+#define    MASTER_STOP_COMMAND     (1 << 5)
+
+#define    TX_ACK       (1 << 0)
+#define    TX_NACK      (1 << 1)
+#define    RX_DONE      (1 << 2)
+#define    STOP_DONE    (1 << 4)
+
+
+ 
+#endif  /* _SMC_91111_H_ */
+
+
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 123092d..f60078c7 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -679,4 +679,10 @@ config RTC_DRV_STARFIRE
 	  If you say Y here you will get support for the RTC found on
 	  Starfire systems.
 
+config RTC_DRV_ASPEED
+	bool "ASPEED RTC"
+	depends on ARM
+	help
+	  RTC driver for ASPEED chips.
+
 endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 6e79c91..7a16fed 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -70,3 +70,4 @@ obj-$(CONFIG_RTC_DRV_V3020)	+= rtc-v3020.o
 obj-$(CONFIG_RTC_DRV_VR41XX)	+= rtc-vr41xx.o
 obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o
 obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
+obj-$(CONFIG_RTC_DRV_ASPEED)	+= rtc-aspeed.o
diff --git a/drivers/rtc/rtc-aspeed.c b/drivers/rtc/rtc-aspeed.c
new file mode 100755
index 0000000..477032e
--- /dev/null
+++ b/drivers/rtc/rtc-aspeed.c
@@ -0,0 +1,495 @@
+/********************************************************************************
+* File Name     : drivers/rtc/rtc-ast.c
+* Author        : Ryan chen
+* Description   : ASPEED Real Time Clock Driver (RTC)
+*
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+* History      :
+*    1. 2012/09/21 ryan chen create this file
+*
+********************************************************************************/
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/rtc.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+
+#include <plat/regs-rtc.h>
+
+struct ast_rtc {
+        void __iomem *base;
+        int irq;
+        struct resource *res;
+        struct rtc_device *rtc_dev;
+        spinlock_t lock;
+};
+
+//static char banner[] = "ASPEED RTC, (C) ASPEED Technology Inc.\n";
+//#define CONFIG_RTC_DEBUG
+
+
+static inline u32
+rtc_read(void __iomem *base, u32 reg)
+{
+#ifdef CONFIG_RTC_DEBUG
+        int val = readl(base + reg);
+        pr_debug("base = 0x%p, offset = 0x%08x, value = 0x%08x\n", base, reg, val);
+        return val;
+#else
+        return readl(base + reg);
+#endif
+}
+
+static inline void
+rtc_write(void __iomem * base, u32 val, u32 reg)
+{
+        pr_debug("base = 0x%p, offset = 0x%08x, data = 0x%08x\n", base, reg, val);
+        writel(val, base + reg);
+}
+
+static int
+ast_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+	struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
+	pr_debug("cmd = 0x%08x, arg = 0x%08lx\n", cmd, arg);
+	
+	switch (cmd) {
+		case RTC_AIE_ON:	/* alarm on */
+			{
+				rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) | ENABLE_ALL_ALARM, RTC_CONTROL);
+				return 0;
+			}
+
+		case RTC_AIE_OFF:	/* alarm off */
+			{
+				rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) &~ENABLE_ALL_ALARM, RTC_CONTROL);
+				return 0;
+			}
+		case RTC_UIE_ON:	/* update on */
+			{
+				pr_debug("no such function \n");
+				return 0;
+			}
+		case RTC_UIE_OFF:	/* update off */
+			{
+				pr_debug("no such function \n");
+				return 0;
+			}
+		case RTC_PIE_OFF:	/* periodic off */
+			{
+				rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) | ENABLE_SEC_INTERRUPT, RTC_CONTROL);
+
+				return 0;
+			}
+		case RTC_PIE_ON:	/* periodic on */
+			{
+				rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) & ~ENABLE_SEC_INTERRUPT, RTC_CONTROL);
+
+				return 0;
+			}
+		default:
+				return -ENOTTY;
+	}
+		
+	return 0;
+}
+
+
+/* Time read/write */
+static int
+ast_rtc_get_time(struct device *dev, struct rtc_time *rtc_tm)
+{
+        struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
+        unsigned long flags;
+        u32 reg_time, reg_date;
+
+        spin_lock_irqsave(&ast_rtc->lock, flags);
+
+		reg_time = rtc_read(ast_rtc->base, RTC_CNTR_STS_1);
+		reg_date = rtc_read(ast_rtc->base, RTC_CNTR_STS_2);
+		
+		spin_unlock_irqrestore(&ast_rtc->lock, flags);
+
+		rtc_tm->tm_year = GET_CENT_VAL(reg_date)*1000 | GET_YEAR_VAL(reg_date);
+		rtc_tm->tm_mon = GET_MON_VAL(reg_date);
+
+		rtc_tm->tm_mday = GET_DAY_VAL(reg_time);
+		rtc_tm->tm_hour = GET_HOUR_VAL(reg_time);
+		rtc_tm->tm_min = GET_MIN_VAL(reg_time);
+		rtc_tm->tm_sec = GET_SEC_VAL(reg_time);
+		
+        pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n",
+                 rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
+                 rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
+		return 0;
+
+}
+
+static int
+ast_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+    struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
+    unsigned long flags;
+    u32 reg_time, reg_date;
+
+	pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n",
+			 tm->tm_year, tm->tm_mon, tm->tm_mday,
+			 tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+    spin_lock_irqsave(&ast_rtc->lock, flags);
+
+	/* set hours */
+	reg_time = SET_DAY_VAL(tm->tm_mday) | SET_HOUR_VAL(tm->tm_hour) | SET_MIN_VAL(tm->tm_min) | SET_SEC_VAL(tm->tm_sec);
+	
+	/* set century */
+	/* set mon */
+	reg_date = SET_CENT_VAL(tm->tm_year / 1000) |  SET_YEAR_VAL(tm->tm_year % 1000) | SET_MON_VAL(tm->tm_mon);
+
+	rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) | RTC_LOCK, RTC_CONTROL);
+
+	rtc_write(ast_rtc->base, reg_time, RTC_CNTR_STS_1);
+	rtc_write(ast_rtc->base, reg_date, RTC_CNTR_STS_2);
+
+	rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) &~RTC_LOCK , RTC_CONTROL);
+	
+	spin_unlock_irqrestore(&ast_rtc->lock, flags);
+
+	return 0;	
+}
+static int
+ast_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+    struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
+    unsigned long flags;
+    struct rtc_time *alm_tm = &alarm->time;
+    u32 alarm_reg;
+
+    spin_lock_irqsave(&ast_rtc->lock, flags);
+	alarm_reg = rtc_read(ast_rtc->base, RTC_ALARM);
+	spin_unlock_irqrestore(&ast_rtc->lock, flags);
+
+//DAY	
+	alm_tm->tm_mday = GET_DAY_VAL(alarm_reg);
+
+//HR
+	alm_tm->tm_hour = GET_HOUR_VAL(alarm_reg);
+
+//MIN
+	alm_tm->tm_min= GET_MIN_VAL(alarm_reg);
+
+//SEC
+	alm_tm->tm_sec= GET_SEC_VAL(alarm_reg);
+
+    pr_debug("ast_rtc_read_alarm: %d, %02x %02x.%02x.%02x\n",
+             alarm->enabled,
+             alm_tm->tm_mday & 0xff, alm_tm->tm_hour & 0xff, alm_tm->tm_min & 0xff, alm_tm->tm_sec);
+
+	return 0;
+
+
+}
+
+static int
+ast_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+    struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
+    struct rtc_time *tm = &alarm->time;
+    unsigned long flags;
+    u32 reg_alarm = 0;
+
+    pr_debug("ast_rtc_setalarm: %d, %02x %02x.%02x.%02x\n",
+             alarm->enabled,
+             tm->tm_mday & 0xff, tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec);
+
+//DAY
+    /* set day of week */
+    if (tm->tm_mday <= 31 && tm->tm_mday >= 1) {
+			reg_alarm |= SET_DAY_VAL(tm->tm_mday);
+    }
+    
+//HR
+    /* set ten hours */
+    if (tm->tm_hour <= 23 && tm->tm_hour >= 0) {
+            reg_alarm |= SET_HOUR_VAL(tm->tm_hour);
+    }
+
+//MIN
+    /* set ten minutes */
+    if (tm->tm_min <= 59 && tm->tm_min >= 0) {
+            reg_alarm |= SET_MIN_VAL(tm->tm_min);
+    }
+
+//SEC
+    /* set ten secondss */
+    if (tm->tm_sec <= 59 && tm->tm_sec >= 0) {
+            reg_alarm |= SET_SEC_VAL(tm->tm_sec);
+    }
+
+	pr_debug("ast_rtc_set alarm reg: %x \n", reg_alarm);
+
+	spin_lock_irqsave(&ast_rtc->lock, flags);
+
+	rtc_write(ast_rtc->base, reg_alarm, RTC_ALARM);
+	
+	if(alarm->enabled)	
+		rtc_write(ast_rtc->base, reg_alarm, RTC_CONTROL);
+	else
+		rtc_write(ast_rtc->base, reg_alarm, RTC_CONTROL);
+
+	spin_unlock_irqrestore(&ast_rtc->lock, flags);
+	return 0;
+
+}
+static int
+ast_rtc_proc(struct device *dev, struct seq_file *seq)
+{
+        struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
+        u32 ctrl_reg;
+
+        ctrl_reg = rtc_read(ast_rtc->base, RTC_CONTROL);
+
+        pr_debug("ctrl_reg = 0x%08x\n", ctrl_reg);
+
+        seq_printf(seq, "periodic_IRQ\t: %s\n",
+                     (ctrl_reg & ENABLE_SEC_INTERRUPT) ? "yes" : "no" );
+
+        return 0;
+}
+
+static int
+ast_rtc_irq_set_freq(struct device *dev, int freq)
+{
+	struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
+	pr_debug("freq = %d\n", freq);
+
+	spin_lock_irq(&ast_rtc->lock);
+
+	if(freq == 0)
+		rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL)&~ENABLE_SEC_INTERRUPT, RTC_CONTROL);
+	else
+		rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL)|ENABLE_SEC_INTERRUPT, RTC_CONTROL);
+
+	spin_unlock_irq(&ast_rtc->lock);
+
+	return 0;
+}
+
+static irqreturn_t
+ast_rtc_interrupt(int irq, void *dev_id)
+{
+	struct ast_rtc *ast_rtc = dev_id;
+
+	unsigned int status = rtc_read(ast_rtc->base, RTC_ALARM_STS);
+	rtc_write(ast_rtc->base, status, RTC_ALARM_STS);
+
+	if (status & SEC_INTERRUPT_STATUS) {
+        printk("RTC Alarm SEC_INTERRUPT_STATUS!!\n");
+	}
+
+	if (status & DAY_ALARM_STATUS) {
+        printk("RTC Alarm DAY_ALARM_STATUS!!\n");
+	}
+
+	if (status & HOUR_ALARM_STATUS) {
+        printk("RTC Alarm HOUR_ALARM_STATUS!!\n");
+	}
+
+	if (status & MIN_ALARM_STATUS) {
+        printk("RTC Alarm MIN_ALARM_STATUS!!\n");
+	}
+
+	if (status & SEC_ALARM_STATUS) {
+        printk("RTC Alarm SEC_ALARM_STATUS!!\n");
+	}
+
+	rtc_update_irq(ast_rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
+
+	return (IRQ_HANDLED);
+}
+
+static struct rtc_class_ops ast_rtcops = {
+        .ioctl            = ast_rtc_ioctl,
+        .read_time        = ast_rtc_get_time,
+        .set_time         = ast_rtc_set_time,
+        .read_alarm       = ast_rtc_read_alarm,
+        .set_alarm        = ast_rtc_set_alarm,
+        .proc             = ast_rtc_proc,
+        .irq_set_freq     = ast_rtc_irq_set_freq,
+};
+
+/*
+ * Initialize and install RTC driver
+ */
+static int __init ast_rtc_probe(struct platform_device *pdev)
+{
+	struct ast_rtc *ast_rtc;
+	struct rtc_device *rtc_dev;
+	struct resource *res;
+	int ret;
+
+	pr_debug("%s: probe=%p\n", __func__, pdev);
+
+	ast_rtc = kzalloc(sizeof *ast_rtc, GFP_KERNEL);
+	if (!ast_rtc)
+			return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+			dev_err(&pdev->dev, "register resources unusable\n");
+			ret = -ENXIO;
+			goto  free_rtc;
+	}
+
+	ast_rtc->irq = platform_get_irq(pdev, 0);
+	if (ast_rtc->irq < 0) {
+			dev_err(&pdev->dev, "unable to get irq\n");
+			ret = -ENXIO;
+			goto free_rtc;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
+			ret = -EBUSY;
+			goto free_rtc;
+	}
+	
+	ast_rtc->base = ioremap(res->start, resource_size(res));
+	if (!ast_rtc->base) {
+			dev_err(&pdev->dev, "cannot map SocleDev registers\n");
+			ret = -ENOMEM;
+			goto release_mem;
+	}
+	
+	pr_debug("base = 0x%p, irq = %d\n", ast_rtc->base, ast_rtc->irq);
+
+	rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &ast_rtcops, THIS_MODULE);
+	if (IS_ERR(rtc_dev)) {
+			ret = PTR_ERR(rtc_dev);
+			goto unmap;
+	}
+	
+	ast_rtc->res = res;
+	ast_rtc->rtc_dev = rtc_dev;
+	spin_lock_init(&ast_rtc->lock);
+
+	platform_set_drvdata(pdev, ast_rtc);
+
+//	ast_rtc_irq_set_freq(&pdev->dev, 1);
+
+	/* start the RTC from dddd:hh:mm:ss = 0000:00:00:00 */
+	spin_lock_irq(&ast_rtc->lock);
+	if(!(rtc_read(ast_rtc->base, RTC_CONTROL) & RTC_ENABLE)) {
+		//combination mode
+		rtc_write(ast_rtc->base, ALARM_MODE_SELECT | RTC_LOCK | RTC_ENABLE, RTC_CONTROL);
+
+		rtc_write(ast_rtc->base, 0, RTC_CNTR_STS_1);
+
+		rtc_write(ast_rtc->base, 0, RTC_CNTR_STS_2);
+
+		rtc_write(ast_rtc->base, 0, RTC_ALARM);
+		rtc_write(ast_rtc->base, ~RTC_LOCK & rtc_read(ast_rtc->base, RTC_CONTROL), RTC_CONTROL);
+	} else
+		printk("no need to enable RTC \n");
+
+	spin_unlock_irq(&ast_rtc->lock);
+	
+	/* register ISR */
+	ret = request_irq(ast_rtc->irq, ast_rtc_interrupt, IRQF_DISABLED, dev_name(&rtc_dev->dev), ast_rtc);
+	if (ret) {
+		printk(KERN_ERR "ast_rtc: IRQ %d already in use.\n",
+				ast_rtc->irq);
+		goto unregister;
+	}
+
+	return 0;
+
+unregister:
+	rtc_device_unregister(rtc_dev);
+	platform_set_drvdata(pdev, NULL);
+unmap:
+	iounmap(ast_rtc->base);
+release_mem:
+	release_mem_region(res->start, resource_size(res));
+free_rtc:
+	kfree(ast_rtc);
+	return ret;
+
+}
+
+/*
+ * Disable and remove the RTC driver
+ */
+static int __exit ast_rtc_remove(struct platform_device *pdev)
+{
+	struct ast_rtc *ast_rtc = platform_get_drvdata(pdev);
+
+	free_irq(IRQ_RTC, pdev);
+	rtc_device_unregister(ast_rtc->rtc_dev);
+	platform_set_drvdata(pdev, NULL);
+	iounmap(ast_rtc->base);
+	release_resource(ast_rtc->res);
+	kfree(ast_rtc);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+/* ASPEED RTC Power management control */
+static int ast_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	return 0;
+}
+
+static int ast_rtc_resume(struct platform_device *pdev)
+{
+	return 0;
+}
+#else
+#define ast_rtc_suspend NULL
+#define ast_rtc_resume  NULL
+#endif
+
+static struct platform_driver ast_rtc_driver = {
+	.probe		= ast_rtc_probe,
+	.remove		= __exit_p(ast_rtc_remove),
+	.suspend	= ast_rtc_suspend,
+	.resume		= ast_rtc_resume,
+	.driver		= {
+		.name	= "ast_rtc",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init ast_rtc_init(void)
+{
+	return platform_driver_register(&ast_rtc_driver);
+}
+
+static void __exit ast_rtc_exit(void)
+{
+	platform_driver_unregister(&ast_rtc_driver);
+}
+
+module_init(ast_rtc_init);
+module_exit(ast_rtc_exit);
+
+MODULE_AUTHOR("Ryan Chen");
+MODULE_DESCRIPTION("RTC driver for ASPEED AST ");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ast_rtc");
+
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 579d63a..5666583 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -137,6 +137,34 @@ config SERIAL_8250_RUNTIME_UARTS
 	  with the module parameter "nr_uarts", or boot-time parameter
 	  8250.nr_uarts
 
+config SERIAL_AST_DMA_UART
+        tristate "AST UART driver with DMA"
+        depends on ARCH_ASPEED
+        select SERIAL_CORE
+        help
+          The ASPEED UART driver with DMA supporting. The device node is /dev/ttyDMA
+
+config AST_NR_DMA_UARTS
+        int "Maximum number of ast1070 uart dma serial ports"
+        depends on SERIAL_AST_DMA_UART
+        default "4"
+        help
+          Set this to the number of serial ports you want the driver
+          to support.  This includes any ports discovered via ACPI or
+          PCI enumeration and any ports that may be added at run-time
+          via hot-plug, or any ISA multi-port serial cards.
+
+config AST_RUNTIME_DMA_UARTS
+        int "Number of ast1070 uart dma serial ports to register at runtime"
+        depends on SERIAL_AST_DMA_UART
+        range 0 AST_NR_DMA_UARTS
+        default "4"
+        help
+          Set this to the maximum number of serial ports you want
+          the kernel to register at boot time.  This can be overridden
+          with the module parameter "nr_uarts", or boot-time parameter
+          8250.nr_uarts
+
 config SERIAL_8250_EXTENDED
 	bool "Extended 8250/16550 serial driver options"
 	depends on SERIAL_8250
@@ -510,6 +538,39 @@ config SERIAL_S3C2440
 
 
 
+config SERIAL_AST
+	tristate "ASPEED serial port support"
+	depends on ARCH_ASPEED
+	select SERIAL_CORE
+	help
+	  Support for the on-chip UARTs on the ASPEED chips,
+	  providing /dev/ttySAC0, 1 and 2 (note, some machines may not
+	  provide all of these ports, depending on how the serial port
+	  pins are configured.
+
+config SERIAL_ASPEED_CONSOLE
+	bool "Support for console on ASPEED serial port"
+	depends on SERIAL_AST=y
+	select SERIAL_CORE_CONSOLE
+	help
+	  Allow selection of the ASPEED on-board serial ports for use as
+	  an virtual console.
+
+	  Even if you say Y here, the currently visible virtual console
+	  (/dev/ttyS0) will still be used as the system console by default, but
+	  you can alter that using a kernel command line option such as
+	  "console=ttySx". (Try "man bootparam" or see the documentation of
+	  your boot loader about how to pass options to the kernel at
+	  boot time.)
+
+config SERIAL_ASPEED_CONSOLE_BAUD
+	int "ASPEED serial port baud"
+	depends on SERIAL_ASPEED_CONSOLE=y
+	default "115200"
+	help
+	  Select the ASPEED console baud rate.
+	  This value is only used if the bootloader doesn't pass in the
+
 config SERIAL_DZ
 	bool "DECstation DZ serial driver"
 	depends on MACH_DECSTATION && 32BIT
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 0c17c8d..9a0059f 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o
 obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o
 obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o
 obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o
+obj-$(CONFIG_SERIAL_AST)	+= ast_serial.o
 obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o
 obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o
 obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o
@@ -28,6 +29,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
 obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
 obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
 obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
+obj-$(CONFIG_SERIAL_AST_DMA_UART) += ast1070_dma_uart.o
 obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
 obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
 obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
diff --git a/drivers/serial/ast1070_dma_uart.c b/drivers/serial/ast1070_dma_uart.c
new file mode 100644
index 0000000..16eb3c5
--- /dev/null
+++ b/drivers/serial/ast1070_dma_uart.c
@@ -0,0 +1,1511 @@
+/********************************************************************************
+* File Name     : ast1070_dma_uart.c
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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/module.h>
+#include <linux/moduleparam.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_reg.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/nmi.h>
+#include <linux/mutex.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "8250.h"
+#include <linux/dma-mapping.h>
+#include <linux/miscdevice.h>
+#include <plat/regs-uart-dma.h>
+#include <mach/ast-uart-dma.h>
+
+//#define CONFIG_UART_DMA_DEBUG
+
+#ifdef CONFIG_UART_DMA_DEBUG
+	#define DBG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
+#else
+	#define DBG(fmt, args...)
+#endif
+
+/*
+ * Configuration:
+ *   share_irqs - whether we pass IRQF_SHARED to request_irq().  This option
+ *                is unsafe when used on edge-triggered interrupts.
+ */
+static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
+
+static unsigned int nr_uarts = CONFIG_AST_RUNTIME_DMA_UARTS;
+
+/*
+ * Debugging.
+ */
+#if 0
+#define DEBUG_AUTOCONF(fmt...)	printk(fmt)
+#else
+#define DEBUG_AUTOCONF(fmt...)	do { } while (0)
+#endif
+
+#if 0
+#define DEBUG_INTR(fmt...)	printk(fmt)
+#else
+#define DEBUG_INTR(fmt...)	do { } while (0)
+#endif
+
+#define PASS_LIMIT	256
+
+#include <asm/serial.h>
+
+
+#define UART_DMA_NR		CONFIG_AST_NR_DMA_UARTS
+
+struct ast_uart_port {
+	struct uart_port	port;
+	unsigned short		capabilities;	/* port capabilities */
+	unsigned short		bugs;		/* port bugs */
+	unsigned int		tx_loadsz;	/* transmit fifo load size */
+	unsigned char		acr;
+	unsigned char		ier;
+	unsigned char		lcr;
+	unsigned char		mcr;
+	unsigned char		mcr_mask;	/* mask of user bits */
+	unsigned char		mcr_force;	/* mask of forced bits */
+	struct circ_buf		rx_dma_buf;
+	struct circ_buf		tx_dma_buf;
+	dma_addr_t			dma_rx_addr;	/* Mapped ADMA descr. table */
+	dma_addr_t			dma_tx_addr;	/* Mapped ADMA descr. table */
+	unsigned int 	dma_buf_size;	//total allocation dma size ..
+	struct tasklet_struct	rx_tasklet;
+	int rx_tasklet_done;
+	struct tasklet_struct	tx_tasklet;
+	spinlock_t lock;
+	int tx_done;
+	int tx_count;
+	/*
+	 * Some bits in registers are cleared on a read, so they must
+	 * be saved whenever the register is read but the bits will not
+	 * be immediately processed.
+	 */
+#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
+	unsigned char		lsr_saved_flags;
+#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
+	unsigned char		msr_saved_flags;
+
+	/*
+	 * We provide a per-port pm hook.
+	 */
+	void			(*pm)(struct uart_port *port,
+				      unsigned int state, unsigned int old);
+};
+
+static struct ast_uart_port ast_uart_ports[UART_DMA_NR];
+
+static inline struct ast_uart_port *
+to_ast_dma_uart_port(struct uart_port *uart)
+{
+	return container_of(uart, struct ast_uart_port, port);
+}
+
+struct irq_info {
+	spinlock_t		lock;
+	struct ast_uart_port *up;
+};
+
+static struct irq_info ast_uart_irq[1];
+static DEFINE_MUTEX(ast_uart_mutex);
+
+/*
+ * Here we define the default xmit fifo size used for each type of UART.
+ */
+static const struct serial8250_config uart_config[] = {
+	[PORT_UNKNOWN] = {
+		.name		= "unknown",
+		.fifo_size	= 1,
+		.tx_loadsz	= 1,
+	},
+	[PORT_8250] = {
+		.name		= "8250",
+		.fifo_size	= 1,
+		.tx_loadsz	= 1,
+	},
+	[PORT_16450] = {
+		.name		= "16450",
+		.fifo_size	= 1,
+		.tx_loadsz	= 1,
+	},
+	[PORT_16550] = {
+		.name		= "16550",
+		.fifo_size	= 1,
+		.tx_loadsz	= 1,
+	},
+	[PORT_16550A] = {
+		.name		= "16550A",
+		.fifo_size	= 16,
+		.tx_loadsz	= 16,
+		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | UART_FCR_DMA_SELECT,
+		.flags		= UART_CAP_FIFO,
+	},
+};
+
+/* sane hardware needs no mapping */
+#define map_8250_in_reg(up, offset) (offset)
+#define map_8250_out_reg(up, offset) (offset)
+
+void ast_uart_unregister_port(int line);
+int ast_uart_register_port(struct uart_port *port);
+
+static unsigned int serial_in(struct ast_uart_port *up, int offset)
+{
+	offset = map_8250_in_reg(up, offset) << up->port.regshift;
+
+		return readb(up->port.membase + offset);
+}
+
+static void
+serial_out(struct ast_uart_port *up, int offset, int value)
+{
+	/* Save the offset before it's remapped */
+	offset = map_8250_out_reg(up, offset) << up->port.regshift;
+
+		writeb(value, up->port.membase + offset);
+}
+
+
+/*
+ * We used to support using pause I/O for certain machines.  We
+ * haven't supported this for a while, but just in case it's badly
+ * needed for certain old 386 machines, I've left these #define's
+ * in....
+ */
+#define serial_inp(up, offset)		serial_in(up, offset)
+#define serial_outp(up, offset, value)	serial_out(up, offset, value)
+
+/* Uart divisor latch read */
+static inline int _serial_dl_read(struct ast_uart_port *up)
+{
+	return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8;
+}
+
+/* Uart divisor latch write */
+static inline void _serial_dl_write(struct ast_uart_port *up, int value)
+{
+	serial_outp(up, UART_DLL, value & 0xff);
+	serial_outp(up, UART_DLM, value >> 8 & 0xff);
+}
+
+#define serial_dl_read(up) _serial_dl_read(up)
+#define serial_dl_write(up, value) _serial_dl_write(up, value)
+
+static void ast_uart_tx_tasklet_func(unsigned long data)
+{
+	struct ast_uart_port *up = to_ast_dma_uart_port((struct uart_port *)data);
+	struct circ_buf *xmit = &up->port.info->xmit;
+	struct ast_uart_dma_data *uart_dma_data = up->port.private_data;
+	
+	up->tx_done = 0;
+	DBG("line [%d], xmit->head =%d, xmit->tail = %d\n",up->port.line,xmit->head, xmit->tail);
+
+	if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
+		up->tx_count = 0;
+		up->tx_done = 1;
+		return;
+	}
+
+	if (up->port.x_char) {
+		serial_outp(up, UART_TX, up->port.x_char);
+		up->port.icount.tx++;
+		up->port.x_char = 0;
+		return;
+	}
+
+	up->tx_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE);
+
+	if (up->tx_count > (UART_XMIT_SIZE - xmit->tail)) {
+		up->tx_count = UART_XMIT_SIZE - xmit->tail;
+	}
+
+	if (up->tx_count > 4095) {
+		printk("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! TODO ....\n");
+		up->tx_count = 4095;
+	}
+
+	ast_uart_tx_dma_ctrl(uart_dma_data->chip_no, 
+					uart_dma_data->dma_ch, AST_UART_DMAOP_STOP);
+
+	ast_uart_tx_dma_enqueue(uart_dma_data->chip_no, 
+					uart_dma_data->dma_ch, up->dma_tx_addr, up->tx_count);
+
+	dma_sync_single_for_device(up->port.dev,
+				   up->dma_tx_addr,
+				   up->tx_count,
+				   DMA_TO_DEVICE);
+
+	ast_uart_tx_dma_ctrl(uart_dma_data->chip_no, 
+					uart_dma_data->dma_ch, AST_UART_DMAOP_TRIGGER);
+
+
+}
+
+static void ast_uart_tx_buffdone(struct ast1070_dma_ch *dma_ch, void *dev_id, u16 len)
+{
+	struct ast_uart_port *up = (struct ast_uart_port *) dev_id;
+	struct circ_buf *xmit = &up->port.info->xmit;
+
+	DBG("line [%d] : tx len = %d \n", up->port.line, len);	
+	
+	spin_lock(&up->port.lock);
+//TODO .....................................len ----> 
+	xmit->tail = (xmit->tail + up->tx_count) & (UART_XMIT_SIZE - 1);
+	up->port.icount.tx += up->tx_count;
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+			uart_write_wakeup(&up->port);
+
+	tasklet_schedule(&up->tx_tasklet);
+
+	spin_unlock(&up->port.lock);
+}
+
+static void ast_uart_rx_tasklet_func(unsigned long data)
+{
+	struct ast_uart_port *up = to_ast_dma_uart_port((struct uart_port *)data);
+	struct circ_buf *rx_ring = &up->rx_dma_buf;
+	struct tty_struct *tty = up->port.info->port.tty;
+	char flag;	
+	DBG("line [%d]\n",up->port.line);
+	DBG("rx_ring->head = %d, rx_ring->tail = %d , buff addr = %x \n",rx_ring->head, rx_ring->tail, rx_ring->buf);
+
+	spin_lock_irq(&up->lock);
+#if 1 	
+	DBG("\n rx data :  -- >");
+
+	while (rx_ring->head != rx_ring->tail) {
+		DBG("  %x ",rx_ring->buf[rx_ring->tail]);
+		flag = TTY_NORMAL;
+		uart_insert_char(&up->port, 0, UART_LSR_OE, \
+			rx_ring->buf[rx_ring->tail], flag);
+
+//		tty_insert_flip_string
+
+		rx_ring->tail++;
+		if (rx_ring->tail == up->dma_buf_size)
+			rx_ring->tail = 0;
+	}
+	DBG("\n");
+#else
+	
+	tty_insert_flip_string(tty, rx_ring->buf + rx_ring->tail, (rx_ring->head - rx_ring->tail));
+	rx_ring->tail = rx_ring->head;
+#endif
+	spin_unlock_irq(&up->lock);
+
+	spin_unlock(&up->port.lock);
+	tty_flip_buffer_push(tty);
+	spin_lock(&up->port.lock);
+
+
+}
+
+static void ast_uart_rx_buffdone(struct ast1070_dma_ch *dma_ch,
+				void *dev_id, u16 len)
+{
+	struct ast_uart_port *up = (struct ast_uart_port *)dev_id;
+//	struct tty_struct *tty = up->port.info->port.tty;
+	struct circ_buf *rx_ring = &up->rx_dma_buf;
+	struct ast_uart_dma_data *uart_dma_data = up->port.private_data;
+	u16 remain_size;
+
+	DBG("line [%d]\n",up->port.line);
+#if 0
+	int i;
+	printk("Buff virt addr = %x \n",rx_ring->buf);
+	for(i=0;i<len;i++)
+		printk("Buff [%x] \n", rx_ring->buf[up->rx_dma_buf.head + i]);
+#endif
+	DBG("head = %d, len : %d\n",up->rx_dma_buf.head, len);
+
+
+	//FOR NEXT ......
+	rx_ring->head += len;
+	
+	if (rx_ring->head == up->dma_buf_size) {
+		rx_ring->head = 0;
+	}
+
+	remain_size = up->dma_buf_size - rx_ring->head;
+
+	//Trigger Next RX dma
+	DBG("trigger next size = %d \n",remain_size);	
+	
+	ast_uart_rx_dma_ctrl(uart_dma_data->chip_no, 
+						uart_dma_data->dma_ch, AST_UART_DMAOP_STOP);
+
+	if(remain_size > DMA_BUFF_SIZE)
+		printk("Please check ---> \n");
+	
+	if(remain_size != 0)  {
+		ast_uart_rx_dma_enqueue(uart_dma_data->chip_no, 
+							uart_dma_data->dma_ch, up->dma_rx_addr + up->rx_dma_buf.head, remain_size);
+	} 
+	ast_uart_rx_dma_ctrl(uart_dma_data->chip_no, 
+						uart_dma_data->dma_ch, AST_UART_DMAOP_TRIGGER);
+
+	tasklet_schedule(&up->rx_tasklet);
+
+}
+
+/*
+ * FIFO support.
+ */
+static inline void serial8250_clear_fifos(struct ast_uart_port *p)
+{
+	serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO);
+	serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO |
+		       UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+	serial_outp(p, UART_FCR, 0);
+}
+
+
+/*
+ * This routine is called by rs_init() to initialize a specific serial
+ * port.
+ */
+static void autoconfig(struct ast_uart_port *up, unsigned int probeflags)
+{
+	unsigned long flags;
+
+	if (!up->port.iobase && !up->port.mapbase && !up->port.membase)
+		return;
+
+	DEBUG_AUTOCONF("ttyDMA%d: autoconf (0x%04x, 0x%p): ",
+			up->port.line, up->port.iobase, up->port.membase);
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	up->capabilities = 0;
+	up->bugs = 0;
+
+	up->port.type = PORT_16550A;
+	up->capabilities |= UART_CAP_FIFO;
+
+	up->port.fifosize = uart_config[up->port.type].fifo_size;
+	up->capabilities = uart_config[up->port.type].flags;
+	up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
+
+	if (up->port.type == PORT_UNKNOWN)
+		goto out;
+
+	/*
+	 * Reset the UART.
+	 */
+	serial8250_clear_fifos(up);
+	serial_in(up, UART_RX);
+	serial_outp(up, UART_IER, 0);
+
+ out:
+	spin_unlock_irqrestore(&up->port.lock, flags);
+	DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
+}
+
+
+static inline void __stop_tx(struct ast_uart_port *p)
+{
+	if (p->ier & UART_IER_THRI) {
+		p->ier &= ~UART_IER_THRI;
+		serial_out(p, UART_IER, p->ier);
+	}
+}
+
+static void serial8250_stop_tx(struct uart_port *port)
+{
+	struct ast_uart_port *up = to_ast_dma_uart_port(port);
+
+	__stop_tx(up);
+
+}
+
+static void transmit_chars(struct ast_uart_port *up);
+
+static void serial8250_start_tx(struct uart_port *port)
+{
+	struct ast_uart_port *up = to_ast_dma_uart_port(port);
+
+	DBG("line [%d] -->  \n", port->line);
+	if (up->tx_done)
+		tasklet_schedule(&up->tx_tasklet);
+}
+
+static void serial8250_stop_rx(struct uart_port *port)
+{
+	struct ast_uart_port *up = to_ast_dma_uart_port(port);
+
+	DBG("line [%d] -->	\n", port->line);
+	up->ier &= ~UART_IER_RLSI;
+	up->port.read_status_mask &= ~UART_LSR_DR;
+	serial_out(up, UART_IER, up->ier);
+}
+
+static void serial8250_enable_ms(struct uart_port *port)
+{
+	struct ast_uart_port *up = to_ast_dma_uart_port(port);
+
+	up->ier |= UART_IER_MSI;
+	serial_out(up, UART_IER, up->ier);
+}
+
+static void transmit_chars(struct ast_uart_port *up)
+{
+	struct circ_buf *xmit = &up->port.info->xmit;
+	int count;
+
+	if (up->port.x_char) {
+		serial_outp(up, UART_TX, up->port.x_char);
+		up->port.icount.tx++;
+		up->port.x_char = 0;
+		return;
+	}
+	if (uart_tx_stopped(&up->port)) {
+		serial8250_stop_tx(&up->port);
+		return;
+	}
+	if (uart_circ_empty(xmit)) {
+		__stop_tx(up);
+		return;
+	}
+
+//	printk("uart_circ_chars_pending=%d\n",uart_circ_chars_pending(xmit));
+
+	count = up->tx_loadsz;
+	do {
+//printk("TX : buf = 0x%x\n", xmit->buf[xmit->tail]);
+		serial_out(up, UART_TX, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		up->port.icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (--count > 0);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(&up->port);
+
+	DEBUG_INTR("THRE...");
+
+	if (uart_circ_empty(xmit))
+		__stop_tx(up);
+}
+
+static unsigned int check_modem_status(struct ast_uart_port *up)
+{
+	unsigned int status = serial_in(up, UART_MSR);
+
+	status |= up->msr_saved_flags;
+	up->msr_saved_flags = 0;
+	if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
+	    up->port.info != NULL) {
+		if (status & UART_MSR_TERI)
+			up->port.icount.rng++;
+		if (status & UART_MSR_DDSR)
+			up->port.icount.dsr++;
+		if (status & UART_MSR_DDCD)
+			uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
+		if (status & UART_MSR_DCTS)
+			uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
+
+		wake_up_interruptible(&up->port.info->delta_msr_wait);
+	}
+
+	return status;
+}
+
+/*
+ * This handles the interrupt from one port.
+ */
+static inline void
+serial8250_handle_port(struct ast_uart_port *up)
+{
+	unsigned int status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	DEBUG_INTR("serial8250_handle_port \n");
+
+	status = serial_inp(up, UART_LSR);
+
+	DEBUG_INTR("status = %x...", status);
+
+	check_modem_status(up);
+	if (status & UART_LSR_THRE)
+		transmit_chars(up);
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+/*
+ * This is the serial driver's interrupt routine.
+ */
+static irqreturn_t ast_uart_interrupt(int irq, void *dev_id)
+{
+	struct irq_info *i = dev_id;
+	int pass_counter = 0, handled = 0, end = 0;
+
+	DEBUG_INTR("ast_uart_interrupt(%d)...", irq);
+	spin_lock(&i->lock);
+
+	do {
+		struct ast_uart_port *up;
+		unsigned int iir;
+
+		up = (struct ast_uart_port *)(i->up);
+
+		iir = serial_in(up, UART_IIR);
+		DEBUG_INTR("iir %x \n", iir);
+		if (!(iir & UART_IIR_NO_INT)) {
+			printk("handle port \n");
+			serial8250_handle_port(up);
+			handled = 1;
+
+		}
+		else
+			end = 1;
+
+		if (pass_counter++ > PASS_LIMIT) {
+			/* If we hit this, we're dead. */
+			printk(KERN_ERR "ast-uart-dma: too much work for "
+				"irq%d\n", irq);
+			break;
+		}
+	} while (end);
+
+	spin_unlock(&i->lock);
+
+	DEBUG_INTR("end.\n");
+
+	return IRQ_RETVAL(handled);
+}
+
+static unsigned int serial8250_tx_empty(struct uart_port *port)
+{
+	struct ast_uart_port *up = to_ast_dma_uart_port(port);
+	unsigned long flags;
+	unsigned int lsr;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	lsr = serial_in(up, UART_LSR);
+	up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
+}
+
+static unsigned int serial8250_get_mctrl(struct uart_port *port)
+{
+	struct ast_uart_port *up = to_ast_dma_uart_port(port);
+	unsigned int status;
+	unsigned int ret;
+
+	status = check_modem_status(up);
+
+	ret = 0;
+	if (status & UART_MSR_DCD)
+		ret |= TIOCM_CAR;
+	if (status & UART_MSR_RI)
+		ret |= TIOCM_RNG;
+	if (status & UART_MSR_DSR)
+		ret |= TIOCM_DSR;
+	if (status & UART_MSR_CTS)
+		ret |= TIOCM_CTS;
+	return ret;
+}
+
+static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	struct ast_uart_port *up = to_ast_dma_uart_port(port);
+	unsigned char mcr = 0;
+
+	if (mctrl & TIOCM_RTS)
+		mcr |= UART_MCR_RTS;
+	if (mctrl & TIOCM_DTR)
+		mcr |= UART_MCR_DTR;
+	if (mctrl & TIOCM_OUT1)
+		mcr |= UART_MCR_OUT1;
+	if (mctrl & TIOCM_OUT2)
+		mcr |= UART_MCR_OUT2;
+	if (mctrl & TIOCM_LOOP)
+		mcr |= UART_MCR_LOOP;
+
+	mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
+
+	serial_out(up, UART_MCR, mcr);
+}
+
+static void serial8250_break_ctl(struct uart_port *port, int break_state)
+{
+	struct ast_uart_port *up = to_ast_dma_uart_port(port);
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	if (break_state == -1)
+		up->lcr |= UART_LCR_SBC;
+	else
+		up->lcr &= ~UART_LCR_SBC;
+	serial_out(up, UART_LCR, up->lcr);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static int serial8250_startup(struct uart_port *port)
+{
+	struct ast_uart_port *up = to_ast_dma_uart_port(port);
+	//TX DMA 
+	struct circ_buf *xmit = &port->info->xmit;
+	struct ast_uart_dma_data *uart_dma_data = up->port.private_data;
+	unsigned long flags;
+	unsigned char lsr, iir;
+	int retval;
+	int irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
+
+	DBG("line [%d] \n",port->line);
+	
+	up->capabilities = uart_config[up->port.type].flags;
+	up->mcr = 0;
+	
+	/*
+	 * Clear the FIFO buffers and disable them.
+	 * (they will be reenabled in set_termios())
+	 */
+	serial8250_clear_fifos(up);
+
+	/*
+	 * Clear the interrupt registers.
+	 */
+	(void) serial_inp(up, UART_LSR);
+	(void) serial_inp(up, UART_RX);
+	(void) serial_inp(up, UART_IIR);
+	(void) serial_inp(up, UART_MSR);
+
+	ast_uart_irq[0].up = up;
+	retval = request_irq(up->port.irq, ast_uart_interrupt,
+				 irq_flags, "ast-uart-dma", ast_uart_irq);
+	if (retval)
+		return retval;
+
+	/*
+	 * Now, initialize the UART
+	 */
+	serial_outp(up, UART_LCR, UART_LCR_WLEN8);
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	up->port.mctrl |= TIOCM_OUT2;
+
+	serial8250_set_mctrl(&up->port, up->port.mctrl);
+
+	/*
+	 * Do a quick test to see if we receive an
+	 * interrupt when we enable the TX irq.
+	 */
+	serial_outp(up, UART_IER, UART_IER_THRI);
+	lsr = serial_in(up, UART_LSR);
+	iir = serial_in(up, UART_IIR);
+	serial_outp(up, UART_IER, 0);
+
+	if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
+		if (!(up->bugs & UART_BUG_TXEN)) {
+			up->bugs |= UART_BUG_TXEN;
+			printk("ttyDMA%d - enabling bad tx status \n",
+				 port->line);
+		}
+	} else {
+		up->bugs &= ~UART_BUG_TXEN;
+	}
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	/*
+	 * Clear the interrupt registers again for luck, and clear the
+	 * saved flags to avoid getting false values from polling
+	 * routines or the previous session.
+	 */
+	serial_inp(up, UART_LSR);
+	serial_inp(up, UART_RX);
+	serial_inp(up, UART_IIR);
+	serial_inp(up, UART_MSR);
+	up->lsr_saved_flags = 0;
+	up->msr_saved_flags = 0;
+
+	//RX DMA
+	up->rx_dma_buf.head = 0;
+	up->rx_dma_buf.tail = 0;
+	up->dma_buf_size = 2048;//DMA_BUFF_SIZE -1;	//4096  is dma size  please check
+#if 0	
+	up->dma_rx_addr = dma_map_single(port->dev,
+					   up->rx_dma_buf.buf,
+					   up->dma_buf_size,
+					   DMA_FROM_DEVICE);
+#else	
+	up->rx_dma_buf.buf = (unsigned char *)dma_alloc_coherent(NULL, 
+								up->dma_buf_size, &up->dma_rx_addr, GFP_KERNEL);
+#endif
+	DBG("RX buff vir = %x, phy = %x \n", up->rx_dma_buf.buf, up->dma_rx_addr);
+
+	ast_uart_rx_dma_ctrl(uart_dma_data->chip_no, uart_dma_data->dma_ch, AST_UART_DMAOP_STOP);
+
+	ast_uart_rx_dma_enqueue(uart_dma_data->chip_no, uart_dma_data->dma_ch, up->dma_rx_addr, up->dma_buf_size);
+	
+	up->rx_tasklet_done = 1;
+	ast_uart_rx_dma_ctrl(uart_dma_data->chip_no, uart_dma_data->dma_ch, AST_UART_DMAOP_TRIGGER);
+
+	up->tx_dma_buf.head = 0;
+	up->tx_dma_buf.buf = xmit->buf;
+	up->dma_tx_addr = dma_map_single(port->dev,
+				       up->tx_dma_buf.buf,
+				       UART_XMIT_SIZE,
+				       DMA_TO_DEVICE);
+	up->tx_done = 1;
+	up->tx_count = 0;
+
+	return 0;
+}
+
+static void serial8250_shutdown(struct uart_port *port)
+{
+	struct ast_uart_port *up = to_ast_dma_uart_port(port);
+	struct ast_uart_dma_data *uart_dma_data = up->port.private_data;
+	unsigned long flags;
+	//int i;
+	DBG("line [%d]\n",port->line);	
+	/*
+	 * Disable interrupts from this port
+	 */
+#if 0
+	for(i=0; i<100; i++) {
+		printk("tx_count_table[%d] = %d\n", i, tx_count_table[i]);
+	}
+#endif
+	
+	up->ier = 0;
+	serial_outp(up, UART_IER, 0);
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	up->port.mctrl &= ~TIOCM_OUT2;
+
+	serial8250_set_mctrl(&up->port, up->port.mctrl);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	/*
+	 * Disable break condition and FIFOs
+	 */
+	serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC);
+	serial8250_clear_fifos(up);
+
+	(void) serial_in(up, UART_RX);
+	
+	ast_uart_rx_dma_ctrl(uart_dma_data->chip_no, uart_dma_data->dma_ch, AST_UART_DMAOP_STOP);
+
+	ast_uart_tx_dma_ctrl(uart_dma_data->chip_no, uart_dma_data->dma_ch, AST_UART_DMAOP_STOP);
+	//TODO .... Free ---- dma 	
+	DBG("free TX , RX buffer \n");
+#if 1	
+	dma_unmap_single(port->dev, up->dma_rx_addr,
+			 up->dma_buf_size,
+			 DMA_FROM_DEVICE);
+#else
+	dma_free_coherent(port->dev, up->dma_buf_size, 
+			up->rx_dma_buf.buf, up->dma_rx_addr);
+#endif
+
+	dma_unmap_single(port->dev, up->dma_tx_addr,
+			 UART_XMIT_SIZE,
+			 DMA_TO_DEVICE);
+
+
+	free_irq(up->port.irq, ast_uart_irq);
+
+}
+
+static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
+{
+	unsigned int quot;
+
+	quot = uart_get_divisor(port, baud);
+
+	return quot;
+}
+
+static void
+serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
+		       struct ktermios *old)
+{
+	struct ast_uart_port *up = to_ast_dma_uart_port(port);
+	unsigned char cval, fcr = 0;
+	unsigned long flags;
+	unsigned int baud, quot;
+
+	switch (termios->c_cflag & CSIZE) {
+	case CS5:
+		cval = UART_LCR_WLEN5;
+		break;
+	case CS6:
+		cval = UART_LCR_WLEN6;
+		break;
+	case CS7:
+		cval = UART_LCR_WLEN7;
+		break;
+	default:
+	case CS8:
+		cval = UART_LCR_WLEN8;
+		break;
+	}
+
+	if (termios->c_cflag & CSTOPB)
+		cval |= UART_LCR_STOP;
+	if (termios->c_cflag & PARENB)
+		cval |= UART_LCR_PARITY;
+	if (!(termios->c_cflag & PARODD))
+		cval |= UART_LCR_EPAR;
+#ifdef CMSPAR
+	if (termios->c_cflag & CMSPAR)
+		cval |= UART_LCR_SPAR;
+#endif
+
+	/*
+	 * Ask the core to calculate the divisor for us.
+	 */
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
+	quot = serial8250_get_divisor(port, baud);
+
+	if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
+		if (baud < 2400)
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+		else
+			fcr = uart_config[up->port.type].fcr;
+	}
+
+	/*
+	 * Ok, we're now changing the port state.  Do it with
+	 * interrupts disabled.
+	 */
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	/*
+	 * Update the per-port timeout.
+	 */
+	uart_update_timeout(port, termios->c_cflag, baud);
+
+	up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+	if (termios->c_iflag & INPCK)
+		up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+	if (termios->c_iflag & (BRKINT | PARMRK))
+		up->port.read_status_mask |= UART_LSR_BI;
+
+	/*
+	 * Characteres to ignore
+	 */
+	up->port.ignore_status_mask = 0;
+	if (termios->c_iflag & IGNPAR)
+		up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+	if (termios->c_iflag & IGNBRK) {
+		up->port.ignore_status_mask |= UART_LSR_BI;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (termios->c_iflag & IGNPAR)
+			up->port.ignore_status_mask |= UART_LSR_OE;
+	}
+
+	/*
+	 * ignore all characters if CREAD is not set
+	 */
+	if ((termios->c_cflag & CREAD) == 0)
+		up->port.ignore_status_mask |= UART_LSR_DR;
+
+	/*
+	 * CTS flow control flag and modem status interrupts
+	 */
+	up->ier &= ~UART_IER_MSI;
+	if (UART_ENABLE_MS(&up->port, termios->c_cflag))
+		up->ier |= UART_IER_MSI;
+
+	serial_out(up, UART_IER, up->ier);
+
+
+	serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
+
+	serial_dl_write(up, quot);
+
+	/*
+	 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
+	 * is written without DLAB set, this mode will be disabled.
+	 */
+
+	serial_outp(up, UART_LCR, cval);		/* reset DLAB */
+	up->lcr = cval;					/* Save LCR */
+		if (fcr & UART_FCR_ENABLE_FIFO) {
+			/* emulated UARTs (Lucent Venus 167x) need two steps */
+			serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+		}
+		serial_outp(up, UART_FCR, fcr);		/* set fcr */
+	serial8250_set_mctrl(&up->port, up->port.mctrl);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+	/* Don't rewrite B0 */
+	if (tty_termios_baud_rate(termios))
+		tty_termios_encode_baud_rate(termios, baud, baud);
+}
+
+static void
+serial8250_pm(struct uart_port *port, unsigned int state,
+	      unsigned int oldstate)
+{
+	struct ast_uart_port *p = (struct ast_uart_port *)port;
+
+	if (p->pm)
+		p->pm(port, state, oldstate);
+}
+
+/*
+ * Resource handling.
+ */
+static int serial8250_request_std_resource(struct ast_uart_port *up)
+{
+	unsigned int size = 8 << up->port.regshift;
+	int ret = 0;
+
+		if (!up->port.mapbase)
+			return ret;
+
+		if (!request_mem_region(up->port.mapbase, size, "ast-uart-dma")) {
+			ret = -EBUSY;
+			return ret;
+		}
+
+		if (up->port.flags & UPF_IOREMAP) {
+			up->port.membase = ioremap_nocache(up->port.mapbase,
+									size);
+			if (!up->port.membase) {
+				release_mem_region(up->port.mapbase, size);
+				ret = -ENOMEM;
+				return ret;
+			}
+		}
+	return ret;
+}
+
+static void serial8250_release_std_resource(struct ast_uart_port *up)
+{
+	unsigned int size = 8 << up->port.regshift;
+
+		if (!up->port.mapbase)
+			return;
+
+		if (up->port.flags & UPF_IOREMAP) {
+			iounmap(up->port.membase);
+			up->port.membase = NULL;
+		}
+
+		release_mem_region(up->port.mapbase, size);
+}
+
+
+static void serial8250_release_port(struct uart_port *port)
+{
+	struct ast_uart_port *up = (struct ast_uart_port *)port;
+
+	serial8250_release_std_resource(up);
+}
+
+static int serial8250_request_port(struct uart_port *port)
+{
+	struct ast_uart_port *up = (struct ast_uart_port *)port;
+	int ret = 0;
+
+	ret = serial8250_request_std_resource(up);
+	if (ret == 0 )
+			serial8250_release_std_resource(up);
+
+	return ret;
+}
+
+static void serial8250_config_port(struct uart_port *port, int flags)
+{
+	struct ast_uart_port *up = (struct ast_uart_port *)port;
+	int probeflags = PROBE_ANY;
+	int ret;
+
+	/*
+	 * Find the region that we can probe for.  This in turn
+	 * tells us whether we can probe for the type of port.
+	 */
+	ret = serial8250_request_std_resource(up);
+	if (ret < 0)
+		return;
+
+	if (flags & UART_CONFIG_TYPE)
+		autoconfig(up, probeflags);
+
+	if (up->port.type == PORT_UNKNOWN)
+		serial8250_release_std_resource(up);
+}
+
+static int
+serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	return 0;
+}
+
+static const char *
+serial8250_type(struct uart_port *port)
+{
+	int type = port->type;
+
+	if (type >= ARRAY_SIZE(uart_config))
+		type = 0;
+	return uart_config[type].name;
+}
+
+static struct uart_ops serial8250_pops = {
+	.tx_empty	= serial8250_tx_empty,
+	.set_mctrl	= serial8250_set_mctrl,
+	.get_mctrl	= serial8250_get_mctrl,
+	.stop_tx	= serial8250_stop_tx,
+	.start_tx	= serial8250_start_tx,
+	.stop_rx	= serial8250_stop_rx,
+	.enable_ms	= serial8250_enable_ms,
+	.break_ctl	= serial8250_break_ctl,
+	.startup	= serial8250_startup,
+	.shutdown	= serial8250_shutdown,
+	.set_termios	= serial8250_set_termios,
+	.pm		= serial8250_pm,
+	.type		= serial8250_type,
+	.release_port	= serial8250_release_port,
+	.request_port	= serial8250_request_port,
+	.config_port	= serial8250_config_port,
+	.verify_port	= serial8250_verify_port,
+};
+
+static void __init serial8250_isa_init_ports(void)
+{
+	static int first = 1;
+	int i;
+
+	if (!first)
+		return;
+	first = 0;
+
+	for (i = 0; i < nr_uarts; i++) {
+		struct ast_uart_port *up = &ast_uart_ports[i];
+
+		up->port.line = i;
+		spin_lock_init(&up->port.lock);
+
+		/*
+		 * ALPHA_KLUDGE_MCR needs to be killed.
+		 */
+		up->mcr_mask = ~ALPHA_KLUDGE_MCR;
+		up->mcr_force = ALPHA_KLUDGE_MCR;
+
+		up->port.ops = &serial8250_pops;
+	}
+
+}
+
+static void __init
+serial8250_register_ports(struct uart_driver *drv, struct device *dev)
+{
+	int i;
+	printk("serial8250_register_ports \n");
+
+	serial8250_isa_init_ports();
+
+	for (i = 0; i < nr_uarts; i++) {
+		struct ast_uart_port *up = &ast_uart_ports[i];
+		up->port.dev = dev;
+		uart_add_one_port(drv, &up->port);
+	}
+}
+
+#define SERIAL8250_CONSOLE	NULL
+
+static struct uart_driver serial8250_reg = {
+	.owner			= THIS_MODULE,
+	.driver_name		= "ast-uart-dma",
+	.dev_name		= "ttyDMA",
+#if 0
+	.major			= TTY_MAJOR,
+	.minor			= 64,
+#else
+	.major			= 204, // like atmel_serial
+	.minor			= 155,
+#endif
+	.nr			= UART_DMA_NR,
+	.cons			= SERIAL8250_CONSOLE,
+};
+
+
+#if 0
+/**
+ *	serial8250_suspend_port - suspend one serial port
+ *	@line:  serial line number
+ *
+ *	Suspend one serial port.
+ */
+void serial8250_suspend_port(int line)
+{
+	uart_suspend_port(&serial8250_reg, &ast_uart_ports[line].port);
+}
+
+/**
+ *	serial8250_resume_port - resume one serial port
+ *	@line:  serial line number
+ *
+ *	Resume one serial port.
+ */
+void serial8250_resume_port(int line)
+{
+	struct ast_uart_port *up = &ast_uart_ports[line];
+
+	uart_resume_port(&serial8250_reg, &up->port);
+}
+#endif
+
+/*
+ * Register a set of serial devices attached to a platform device.  The
+ * list is terminated with a zero flags entry, which means we expect
+ * all entries to have at least UPF_BOOT_AUTOCONF set.
+ */
+static int __devinit serial8250_probe(struct platform_device *dev)
+{
+	struct plat_serial8250_port *p = dev->dev.platform_data;
+	struct uart_port port;
+	struct ast_uart_dma_data *uart_dma_data;
+	int ret, i;
+
+	if(UART_XMIT_SIZE > DMA_BUFF_SIZE)
+		printk("UART_XMIT_SIZE > DMA_BUFF_SIZE : Please Check \n");
+	
+	memset(&port, 0, sizeof(struct uart_port));
+
+	for (i = 0; p && p->flags != 0; p++, i++) {
+		port.iobase		= p->iobase;
+		port.membase		= p->membase;
+		port.irq		= p->irq;
+		port.uartclk		= p->uartclk;
+		port.regshift		= p->regshift;
+		port.iotype		= p->iotype;
+		port.flags		= p->flags;
+		port.mapbase		= p->mapbase;
+		port.hub6		= p->hub6;
+		port.private_data	= p->private_data;
+		port.dev		= &dev->dev;
+		uart_dma_data = p->private_data;
+		if (share_irqs)
+			port.flags |= UPF_SHARE_IRQ;
+		ret = ast_uart_register_port(&port);
+		if (ret < 0) {
+			dev_err(&dev->dev, "unable to register port at index %d "
+				"(IO%lx MEM%llx IRQ%d): %d\n", i,
+				p->iobase, (unsigned long long)p->mapbase,
+				p->irq, ret);
+		}
+//		printk("TODO ...... line = %d \n",i);
+		ret = ast_uart_rx_dma_request(uart_dma_data->chip_no, uart_dma_data->dma_ch, ast_uart_rx_buffdone, &ast_uart_ports[i]);
+		if (ret < 0) {
+			printk("Error : failed to get rx dma channel[%d]\n", uart_dma_data->dma_ch);
+			goto out_ast_uart_unregister_port;
+		}
+
+		ret = ast_uart_tx_dma_request(uart_dma_data->chip_no, uart_dma_data->dma_ch, ast_uart_tx_buffdone, &ast_uart_ports[i]);
+		if (ret < 0) {
+			printk("Error : failed to get tx dma channel[%d]\n", uart_dma_data->dma_ch);
+			return ret;
+		}
+	}
+
+	return 0;
+	
+out_ast_uart_unregister_port:
+	for (i = 0; i < nr_uarts; i++) {
+		struct ast_uart_port *up = &ast_uart_ports[i];
+
+		if (up->port.dev == &dev->dev)
+			ast_uart_unregister_port(i);
+	};
+	return ret;
+
+}
+
+/*
+ * Remove serial ports registered against a platform device.
+ */
+static int __devexit serial8250_remove(struct platform_device *dev)
+{
+	int i;
+
+	for (i = 0; i < nr_uarts; i++) {
+		struct ast_uart_port *up = &ast_uart_ports[i];
+
+		if (up->port.dev == &dev->dev)
+			ast_uart_unregister_port(i);
+	}
+	//TODO ..
+//	pl080_dma_free(uart_dma_rx.channel, (void *)uart_dma_rx.client);
+//	pl080_dma_free(uart_dma_tx.channel, (void *)uart_dma_tx.client);
+	
+	return 0;
+}
+
+static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
+{
+	int i;
+
+	for (i = 0; i < UART_DMA_NR; i++) {
+		struct ast_uart_port *up = &ast_uart_ports[i];
+
+		if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+			uart_suspend_port(&serial8250_reg, &up->port);
+	}
+
+	return 0;
+}
+
+static int serial8250_resume(struct platform_device *dev)
+{
+	int i;
+
+	for (i = 0; i < UART_DMA_NR; i++) {
+		struct ast_uart_port *up = &ast_uart_ports[i];
+
+		if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+			serial8250_resume_port(i);
+	}
+
+	return 0;
+}
+
+static struct platform_driver serial8250_ast_dma_driver = {
+	.probe		= serial8250_probe,
+	.remove		= __devexit_p(serial8250_remove),
+	.suspend	= serial8250_suspend,
+	.resume		= serial8250_resume,
+	.driver		= {
+		.name	= "ast-uart-dma",
+		.owner	= THIS_MODULE,
+	},
+};
+
+/*
+ * This "device" covers _all_ ISA 8250-compatible serial devices listed
+ * in the table in include/asm/serial.h
+ */
+static struct platform_device *serial8250_isa_devs;
+
+/*
+ * serial8250_register_port and serial8250_unregister_port allows for
+ * 16x50 serial ports to be configured at run-time, to support PCMCIA
+ * modems and PCI multiport cards.
+ */
+
+static struct ast_uart_port *serial8250_find_match_or_unused(struct uart_port *port)
+{
+	int i;
+
+	/*
+	 * First, find a port entry which matches.
+	 */
+	for (i = 0; i < nr_uarts; i++)
+		if (uart_match_port(&ast_uart_ports[i].port, port))
+			return &ast_uart_ports[i];
+
+	/*
+	 * We didn't find a matching entry, so look for the first
+	 * free entry.  We look for one which hasn't been previously
+	 * used (indicated by zero iobase).
+	 */
+	for (i = 0; i < nr_uarts; i++)
+		if (ast_uart_ports[i].port.type == PORT_UNKNOWN &&
+		    ast_uart_ports[i].port.iobase == 0)
+			return &ast_uart_ports[i];
+
+	/*
+	 * That also failed.  Last resort is to find any entry which
+	 * doesn't have a real port associated with it.
+	 */
+	for (i = 0; i < nr_uarts; i++)
+		if (ast_uart_ports[i].port.type == PORT_UNKNOWN)
+			return &ast_uart_ports[i];
+
+	return NULL;
+}
+
+/**
+ *	serial8250_register_port - register a serial port
+ *	@port: serial port template
+ *
+ *	Configure the serial port specified by the request. If the
+ *	port exists and is in use, it is hung up and unregistered
+ *	first.
+ *
+ *	The port is then probed and if necessary the IRQ is autodetected
+ *	If this fails an error is returned.
+ *
+ *	On success the port is ready to use and the line number is returned.
+ */
+int ast_uart_register_port(struct uart_port *port)
+{
+	struct ast_uart_port *uart;
+	int ret = -ENOSPC;
+
+	if (port->uartclk == 0)
+		return -EINVAL;
+printk("register port line %d\n",port->line);
+	mutex_lock(&ast_uart_mutex);
+
+	uart = serial8250_find_match_or_unused(port);
+	if (uart) {
+		uart_remove_one_port(&serial8250_reg, &uart->port);
+
+		uart->port.iobase       = port->iobase;
+		uart->port.membase      = port->membase;
+		uart->port.irq          = port->irq;
+		uart->port.uartclk      = port->uartclk;
+		uart->port.fifosize     = port->fifosize;
+		uart->port.regshift     = port->regshift;
+		uart->port.iotype       = port->iotype;
+		uart->port.flags        = port->flags | UPF_BOOT_AUTOCONF;
+		uart->port.mapbase      = port->mapbase;
+		uart->port.private_data = port->private_data;
+		if (port->dev)
+			uart->port.dev = port->dev;
+
+		ret = uart_add_one_port(&serial8250_reg, &uart->port);
+		if (ret == 0)
+			ret = uart->port.line;
+
+		spin_lock_init(&uart->lock);
+
+		tasklet_init(&uart->rx_tasklet, ast_uart_rx_tasklet_func,
+				(unsigned long)uart);
+	
+		tasklet_init(&uart->tx_tasklet, ast_uart_tx_tasklet_func,
+				(unsigned long)uart);
+
+	}
+
+	mutex_unlock(&ast_uart_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL(ast_uart_register_port);
+
+/**
+ *	serial8250_unregister_port - remove a 16x50 serial port at runtime
+ *	@line: serial line number
+ *
+ *	Remove one serial port.  This may not be called from interrupt
+ *	context.  We hand the port back to the our control.
+ */
+void ast_uart_unregister_port(int line)
+{
+	struct ast_uart_port *uart = &ast_uart_ports[line];
+
+	mutex_lock(&ast_uart_mutex);
+	uart_remove_one_port(&serial8250_reg, &uart->port);
+	if (serial8250_isa_devs) {
+		uart->port.flags &= ~UPF_BOOT_AUTOCONF;
+		uart->port.type = PORT_UNKNOWN;
+		uart->port.dev = &serial8250_isa_devs->dev;
+		uart_add_one_port(&serial8250_reg, &uart->port);
+	} else {
+		uart->port.dev = NULL;
+	}
+	mutex_unlock(&ast_uart_mutex);
+}
+EXPORT_SYMBOL(ast_uart_unregister_port);
+
+static int __init ast_uart_init(void)
+{
+	int ret;
+
+	if (nr_uarts > UART_DMA_NR)
+		nr_uarts = UART_DMA_NR;
+
+	printk(KERN_INFO "ast-uart-dma: UART driver with DMA "
+		"%d ports, IRQ sharing %sabled\n", nr_uarts,
+		share_irqs ? "en" : "dis");
+
+		spin_lock_init(&ast_uart_irq[0].lock);
+
+	ret = uart_register_driver(&serial8250_reg);
+	if (ret)
+		goto out;
+
+	serial8250_isa_devs = platform_device_alloc("ast-uart-dma",
+						    PLAT8250_DEV_LEGACY);
+	if (!serial8250_isa_devs) {
+		ret = -ENOMEM;
+		goto unreg_uart_drv;
+	}
+
+	ret = platform_device_add(serial8250_isa_devs);
+	if (ret)
+		goto put_dev;
+
+	serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
+
+	ret = platform_driver_register(&serial8250_ast_dma_driver);
+	if (ret == 0)
+		goto out;
+
+	platform_device_del(serial8250_isa_devs);
+ put_dev:
+	platform_device_put(serial8250_isa_devs);
+ unreg_uart_drv:
+	uart_unregister_driver(&serial8250_reg);
+ out:
+	return ret;
+}
+
+static void __exit ast_uart_exit(void)
+{
+	struct platform_device *isa_dev = serial8250_isa_devs;
+
+	/*
+	 * This tells serial8250_unregister_port() not to re-register
+	 * the ports (thereby making serial8250_ast_dma_driver permanently
+	 * in use.)
+	 */
+	serial8250_isa_devs = NULL;
+
+	platform_driver_unregister(&serial8250_ast_dma_driver);
+	platform_device_unregister(isa_dev);
+
+	uart_unregister_driver(&serial8250_reg);
+}
+
+late_initcall(ast_uart_init);
+module_exit(ast_uart_exit);
+
+#if 0
+EXPORT_SYMBOL(serial8250_suspend_port);
+EXPORT_SYMBOL(serial8250_resume_port);
+#endif
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("AST DMA serial driver");
+MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
diff --git a/drivers/serial/ast_serial.c b/drivers/serial/ast_serial.c
new file mode 100644
index 0000000..d1822e4
--- /dev/null
+++ b/drivers/serial/ast_serial.c
@@ -0,0 +1,675 @@
+/********************************************************************************
+* File Name     : ast_serial.c
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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/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_ASPEED_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+#if defined(CONFIG_COLDFIRE)
+#include <asm/astsim.h>
+#include <asm/ast_serial.h>
+#define UART_NR		1
+
+#elif defined(CONFIG_ARM)
+#include <mach/hardware.h>
+#include <mach/aspeed_serial.h>
+#define UART_NR		2
+
+#else
+#err "NO CONFIG CPU for Serial UART"
+#endif
+
+#define PORT_AST	255
+
+
+
+#define SERIAL_AST_CONSLE_NAME	"ttyS"
+#define SERIAL_AST_TTY_NAME		"ttyS"
+#define SERIAL_AST_DEVFS_NAME	"tts/"
+#define SERIAL_AST_MAJOR	4
+#define SERIAL_AST_MINOR	64
+#define SERIAL_AST_NR	UART_NR
+
+#define CALLOUT_AST_NAME	"cuaam"
+#define CALLOUT_AST_MAJOR	4
+#define CALLOUT_AST_MINOR	65
+#define CALLOUT_AST_NR	UART_NR
+
+
+#ifdef SUPPORT_SYSRQ
+static struct console ast_console;
+#endif
+
+#define MVP2000_ISR_PASS_LIMIT	256
+
+
+/*
+ * Access macros for the UARTs
+ */
+#define UART_GET_CHAR(p)	readl((p)->membase + UART_RBR)
+#define UART_PUT_CHAR(p, v)	writel((v), (p)->membase + UART_THR)
+#define UART_GET_DLL(p)		readl((p)->membase + UART_DLL)
+#define UART_PUT_DLL(p, v)	writel((v), (p)->membase + UART_DLL)
+#define UART_GET_DLH(p)		readl((p)->membase + UART_DLH)
+#define UART_PUT_DLH(p, v)	writel((v), (p)->membase + UART_DLH)
+#define UART_GET_IER(p)		readl((p)->membase + UART_IER)
+#define UART_PUT_IER(p, v)	writel((v), (p)->membase + UART_IER)
+#define UART_GET_IIR(p)		readl((p)->membase + UART_IIR)
+#define UART_GET_FCR(p)		readl((p)->membase + UART_FCR)
+#define UART_PUT_FCR(p, v)	writel((v), (p)->membase + UART_FCR)
+#define UART_GET_LCR(p)		readl((p)->membase + UART_LCR)
+#define UART_PUT_LCR(p, v)	writel((v), (p)->membase + UART_LCR)
+#define UART_GET_LSR(p)		readl((p)->membase + UART_LSR)
+
+#define UART_DUMMY_RSR_RX	256
+#define UART_PORT_SIZE		64
+
+/*
+ * We wrap our port structure around the generic uart_port.
+ */
+struct uart_ast_port {
+	struct uart_port	port;
+};
+
+static void ast_uart_stop_tx(struct uart_port *port)
+{
+	unsigned int cr;
+
+	cr = UART_GET_IER(port);
+	cr &= ~UART_IER_ETEI;
+	UART_PUT_IER(port, cr);
+}
+
+static void ast_uart_start_tx(struct uart_port *port)
+{
+	unsigned int cr;
+
+	cr = UART_GET_IER(port);
+	cr |= UART_IER_ETEI;
+	UART_PUT_IER(port, cr);
+}
+
+static void ast_uart_stop_rx(struct uart_port *port)
+{
+	unsigned int cr;
+
+	cr = UART_GET_IER(port);
+	cr &= ~UART_IER_ERDI;
+	UART_PUT_IER(port, cr);
+}
+
+static void ast_uart_enable_ms(struct uart_port *port)
+{
+	/* printk(KERN_WARNING "ASPEED UART DO NOT Support MODEM operations(emable_ms)\n"); */
+}
+
+static void
+ast_uart_rx_chars(struct uart_port *port)
+{
+	struct tty_struct *tty = port->info->port.tty;
+	unsigned int status, ch, flag, lsr, max_count = 256;
+
+	status = UART_GET_LSR(port);;
+	while ((status & UART_LSR_DR) && max_count--) {
+		
+		ch = UART_GET_CHAR(port);
+		flag = TTY_NORMAL;
+		port->icount.rx++;
+
+		/*
+		 * Note that the error handling code is
+		 * out of the main execution path
+		 */
+		lsr = UART_GET_LSR(port); 
+		if (unlikely(lsr & UART_LSR_ANY)) {
+			if (lsr & UART_LSR_BE) {
+				lsr &= ~(UART_LSR_FE | UART_LSR_PE);
+				port->icount.brk++;
+				if (uart_handle_break(port))
+					goto ignore_char;
+			} else if (lsr & UART_LSR_PE)
+				port->icount.parity++;
+			else if (lsr & UART_LSR_FE)
+				port->icount.frame++;
+			if (lsr & UART_LSR_OE)
+				port->icount.overrun++;
+
+			lsr &= port->read_status_mask;
+
+			if (lsr & UART_LSR_BE)
+				flag = TTY_BREAK;
+			else if (lsr & UART_LSR_PE)
+				flag = TTY_PARITY;
+			else if (lsr & UART_LSR_FE)
+				flag = TTY_FRAME;
+		}
+
+		if (uart_handle_sysrq_char(port, ch & 255))
+			goto ignore_char;
+
+		uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
+
+	ignore_char:
+		status = UART_GET_LSR(port);
+	}
+	tty_flip_buffer_push(tty);
+	return;
+}
+
+static void ast_uart_tx_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->info->xmit;
+	int count;
+
+	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)) {
+		ast_uart_stop_tx(port);
+		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;
+	} while (--count > 0);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (uart_circ_empty(xmit))
+		ast_uart_stop_tx(port);
+}
+
+static irqreturn_t ast_uart_int(int irq, void *dev_id)
+{
+	struct uart_port *port = dev_id;
+	unsigned int status, iir, pass_counter = MVP2000_ISR_PASS_LIMIT;
+
+	spin_lock(&port->lock);
+		
+	status = UART_GET_LSR(port);
+	do {
+		if (status & UART_LSR_DR)
+			ast_uart_rx_chars(port);
+
+		if (status & UART_LSR_THRE) {
+			ast_uart_tx_chars(port);
+                	iir = UART_GET_IIR(port);
+	        }
+
+		if (pass_counter-- == 0)
+			break;
+
+		status = UART_GET_LSR(port);
+	} while (status & (UART_LSR_THRE|UART_LSR_DR));
+	
+	spin_unlock(&port->lock);
+	
+	return IRQ_HANDLED;
+}
+
+static unsigned int ast_uart_tx_empty(struct uart_port *port)
+{
+	return UART_GET_LSR(port) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
+}
+
+static unsigned int ast_uart_get_mctrl(struct uart_port *port)
+{
+	/* printk(KERN_WARNING "ASPEED UART DO NOT Support MODEM operations(get_mctrl)\n"); */
+	return 0;
+}
+
+static void ast_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	/* printk(KERN_WARNING "ASPEED UART DO NOT Support MODEM operations(set_mctrl)\n"); */
+}
+
+static void ast_uart_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned long flags;
+	unsigned int lcr;
+
+	spin_lock_irqsave(&port->lock, flags);
+	lcr = UART_GET_LCR(port);
+	if (break_state == -1)
+		lcr |= UART_LCR_BRK;
+	else
+		lcr &= ~UART_LCR_BRK;
+	UART_PUT_LCR(port, lcr);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int ast_uart_startup(struct uart_port *port)
+{
+	int retval;
+
+	/*
+	 * Allocate the IRQ
+	 */
+	retval = request_irq(port->irq, ast_uart_int, IRQF_DISABLED, "ast_serial", port);
+	if (retval)
+	{
+		printk("ast_uart_startup: Can't Get IRQ\n");
+		return retval;
+	}
+
+	/*
+	 * Finally, enable interrupts
+	 */
+//	IRQ_SET_HIGH_LEVEL(port->irq);
+//	IRQ_SET_LEVEL_TRIGGER(port->irq);
+	UART_PUT_IER(port, UART_IER_ERDI);
+
+	return 0;
+}
+
+static void ast_uart_shutdown(struct uart_port *port)
+{
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(port->irq, port);
+
+	/*
+	 * disable all interrupts, disable the port
+	 */
+	UART_PUT_IER(port, 0);
+
+	/* disable break condition and fifos */
+	UART_PUT_LCR(port, UART_GET_LCR(port)&(~UART_LCR_BRK));
+	UART_PUT_FCR(port, UART_GET_FCR(port)&(~UART_FCR_FIFOE));
+}
+
+static void
+ast_set_termios(struct uart_port *port, struct ktermios *termios,
+		     struct ktermios *old)
+{
+	unsigned int lcr, fcr = 0;
+	unsigned long flags;
+	unsigned int baud, quot;
+	int ch, i;
+ 
+	/*
+	 * Ask the core to calculate the divisor for us.
+	 */
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
+	quot = port->uartclk / (16 * baud);
+
+	switch (termios->c_cflag & CSIZE) {
+	case CS5:
+		lcr = UART_LCR_WLEN_5;
+		break;
+	case CS6:
+		lcr = UART_LCR_WLEN_6;
+		break;
+	case CS7:
+		lcr = UART_LCR_WLEN_7;
+		break;
+	default: // CS8
+		lcr = UART_LCR_WLEN_8;
+		break;
+	}
+	if (termios->c_cflag & CSTOPB)
+		lcr |= UART_LCR_STOP;
+	if (termios->c_cflag & PARENB) {
+		lcr |= UART_LCR_PEN;
+		if (!(termios->c_cflag & PARODD))
+			lcr |= UART_LCR_EPS;
+	}
+	if (port->fifosize > 1)
+		fcr |= (UART_FCR_XMITR|UART_FCR_RCVRR|UART_FCR_FIFOE);
+
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	/*
+	 * Update the per-port timeout.
+	 */
+	uart_update_timeout(port, termios->c_cflag, baud);
+
+	port->read_status_mask = UART_LSR_OE;
+	if (termios->c_iflag & INPCK)
+		port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+	if (termios->c_iflag & (BRKINT | PARMRK))
+		port->read_status_mask |= UART_LSR_BE;
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (termios->c_iflag & IGNPAR)
+		port->ignore_status_mask |= UART_LSR_FE | UART_LSR_PE;
+	if (termios->c_iflag & IGNBRK) {
+		port->ignore_status_mask |= UART_LSR_BE;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (termios->c_iflag & IGNPAR)
+			port->ignore_status_mask |= UART_LSR_OE;
+	}
+
+	/*
+	 * Ignore all characters if CREAD is not set.
+	 */
+	if ((termios->c_cflag & CREAD) == 0)
+		port->ignore_status_mask |= UART_DUMMY_RSR_RX;
+
+
+	/* Set baud rate */
+	UART_PUT_LCR(port, UART_LCR_DLAB);	/* enable Divisor Latach Address Bit */
+	UART_PUT_DLH(port, ((quot >> 8) & 0xFF));
+	UART_PUT_DLL(port, (quot & 0xff));
+
+	UART_PUT_FCR(port, fcr);
+	UART_PUT_LCR(port, lcr);
+	for (i = 0; i < 16; i++) {
+		ch = UART_GET_CHAR (port); /* Clear Timeout Interrupt */
+	}
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *ast_uart_type(struct uart_port *port)
+{
+	return port->type == PORT_AST ? "AST UART" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'
+ */
+static void ast_uart_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 ast_uart_request_port(struct uart_port *port)
+{
+	return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_ast")
+			!= NULL ? 0 : -EBUSY;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void ast_uart_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE) {
+		port->type = PORT_AST;
+		ast_uart_request_port(port);
+	}
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int ast_uart_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	int ret = 0;
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_AST)
+		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 ast_pops = {
+	.tx_empty	= ast_uart_tx_empty,
+	.set_mctrl	= ast_uart_set_mctrl,
+	.get_mctrl	= ast_uart_get_mctrl,
+	.stop_tx	= ast_uart_stop_tx,
+	.start_tx	= ast_uart_start_tx,
+	.stop_rx	= ast_uart_stop_rx,
+	.enable_ms	= ast_uart_enable_ms,
+	.break_ctl	= ast_uart_break_ctl,
+	.startup	= ast_uart_startup,
+	.shutdown	= ast_uart_shutdown,
+	.set_termios	= ast_set_termios,
+	.type		= ast_uart_type,
+	.release_port	= ast_uart_release_port,
+	.request_port	= ast_uart_request_port,
+	.config_port	= ast_uart_config_port,
+	.verify_port	= ast_uart_verify_port,
+};
+
+#if defined(CONFIG_COLDFIRE)
+static struct uart_ast_port ast_ports[UART_NR] = {
+	{
+		.port	= {
+			.membase	= (void *) AST_UART0_BASE,
+			.mapbase	= AST_UART0_BASE,
+			.iotype		= SERIAL_IO_MEM,
+			.irq		= IRQ_UART0,
+			.uartclk	= (24*1000000L),
+			.fifosize	= 16,
+			.ops		= &ast_pops,
+			.flags		= ASYNC_BOOT_AUTOCONF,
+			.line		= 0,
+		},
+	}
+};
+
+#elif defined (CONFIG_ARM)
+static struct uart_ast_port ast_ports[UART_NR] = {
+	{
+		.port	= {
+			.membase	= (void *) (IO_ADDRESS(AST_UART0_BASE)),
+			.mapbase	= AST_UART0_BASE,
+			.iotype		= SERIAL_IO_MEM,
+			.irq		= IRQ_UART0,
+			.uartclk	= (24*1000000L),
+			.fifosize	= 16,
+			.ops		= &ast_pops,
+			.flags		= ASYNC_BOOT_AUTOCONF,
+			.line		= 0,
+		},
+	}
+};
+#else
+#err "ERROR~~~"
+#endif
+
+#ifdef CONFIG_SERIAL_ASPEED_CONSOLE
+
+static void aspeed_console_putchar(struct uart_port *port, int ch)
+{
+	while (!(UART_GET_LSR(port) & UART_LSR_THRE))
+		barrier();
+	UART_PUT_CHAR(port, ch);
+}
+
+static void ast_uart_console_write(struct console *co, const char *s, unsigned int count)
+{
+	struct uart_port *port = &ast_ports[co->index].port;
+	unsigned int status, old_ier;
+
+	/*
+	 *	First save the IER then disable the interrupts
+	 */
+	old_ier = UART_GET_IER(port);
+	UART_PUT_IER(port, 0);
+
+	/*
+	 *	Now, do each character
+	 */
+	uart_console_write(port, s, count, aspeed_console_putchar);
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the IER
+	 */
+	do {
+		status = UART_GET_LSR(port);
+	} while (!(status & UART_LSR_TEMT));
+	UART_PUT_IER(port, old_ier);
+}
+
+static void __init
+ast_uart_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
+{
+	if (UART_GET_IER(port) & UART_IER_ERDI) {
+		unsigned int lcr, quot;
+		lcr = UART_GET_LCR(port);
+
+		*parity = 'n';
+		if (lcr & UART_LCR_PEN) {
+			if (lcr & UART_LCR_EPS)
+				*parity = 'e';
+			else
+				*parity = 'o';
+		}
+
+		switch (lcr & UART_LCR_WLEN_MASK) {
+		case UART_LCR_WLEN_8:
+		default:
+		    *bits = 8;
+		    break;
+		case UART_LCR_WLEN_7:
+		    *bits = 7;
+		    break;
+		case UART_LCR_WLEN_6:
+		    *bits = 6;
+		    break;
+		case UART_LCR_WLEN_5:
+		    *bits = 5;
+		    break;
+		}
+
+		UART_PUT_LCR(port, UART_LCR_DLAB);	/* enable Divisor Latach Address Bit */
+		quot = UART_GET_DLL(port) | (UART_GET_DLH(port) << 8);
+		*baud = port->uartclk / (16 * quot);
+		UART_PUT_LCR(port, lcr);
+	}
+}
+
+static int __init ast_uart_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = CONFIG_SERIAL_ASPEED_CONSOLE_BAUD;
+	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 = &ast_ports[co->index].port;
+
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else	
+	        ast_uart_console_get_options(port, &baud, &parity, &bits);
+
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver ast_reg;
+
+static struct console ast_console = {
+	.name		= SERIAL_AST_CONSLE_NAME,
+	.write		= ast_uart_console_write,
+	.device		= uart_console_device,
+	.setup		= ast_uart_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+	.data		= &ast_reg,
+};
+
+int __init ast_uart_console_init(void)
+{
+	register_console(&ast_console);
+	return 0;
+}
+
+console_initcall(ast_uart_console_init);
+
+#define MVP2000_CONSOLE	&ast_console
+#else
+#define MVP2000_CONSOLE	NULL
+#endif
+
+
+static struct uart_driver ast_reg = {
+	.owner			= THIS_MODULE,	
+	.major			= SERIAL_AST_MAJOR,
+	.minor			= SERIAL_AST_MINOR,	
+	.dev_name		= SERIAL_AST_TTY_NAME,
+	.nr			= UART_NR,
+	.cons			= MVP2000_CONSOLE,
+};
+
+static int __init ast_uart_init(void)
+{
+	int ret;
+
+	ret = uart_register_driver(&ast_reg);
+	if (ret == 0) {
+		int i;
+
+		for (i = 0; i < UART_NR; i++)
+			uart_add_one_port(&ast_reg, &ast_ports[i].port);
+	}
+	return ret;
+}
+
+static void __exit ast_uart_exit(void)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++)
+		uart_remove_one_port(&ast_reg, &ast_ports[i].port);
+
+	uart_unregister_driver(&ast_reg);
+}
+
+module_init(ast_uart_init);
+module_exit(ast_uart_exit);
+
+MODULE_AUTHOR("ASPEED Technology Inc.");
+MODULE_DESCRIPTION("ASPEED serial port driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index b9d0efb..d95c2c8 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -53,6 +53,19 @@ if SPI_MASTER
 
 comment "SPI Master Controller Drivers"
 
+config SPI_AST
+	tristate "Aspeed SPI Controller"
+        depends on ARCH_ASPEED 
+        select SPI_BITBANG
+        help
+          This selects a driver for the AST SPI Controller
+
+config SPI_FMC
+        tristate "Aspeed FMC SPI Controller"
+        depends on ARCH_ASPEED
+        help
+          This selects a driver for the AST FMC SPI Controller
+
 config SPI_ATMEL
 	tristate "Atmel SPI Controller"
 	depends on (ARCH_AT91 || AVR32)
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index ccf18de..3d1286e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -29,6 +29,8 @@ obj-$(CONFIG_SPI_S3C24XX)		+= spi_s3c24xx.o
 obj-$(CONFIG_SPI_TXX9)			+= spi_txx9.o
 obj-$(CONFIG_SPI_XILINX)		+= xilinx_spi.o
 obj-$(CONFIG_SPI_SH_SCI)		+= spi_sh_sci.o
+obj-$(CONFIG_SPI_AST)                   += ast_spi.o
+obj-$(CONFIG_SPI_FMC)                   += fmc_spi.o
 # 	... add above this line ...
 
 # SPI protocol drivers (device/link on bus)
diff --git a/drivers/spi/ast_spi.c b/drivers/spi/ast_spi.c
new file mode 100644
index 0000000..e8f80e8
--- /dev/null
+++ b/drivers/spi/ast_spi.c
@@ -0,0 +1,416 @@
+/********************************************************************************
+* File Name     : driver/spi/ast-spi.c
+* Author        : Ryan Chen
+* Description   : ASPEED SPI host driver
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+*   History      :
+*	1. 2012/10/20 Ryan Chen create this file
+*	1. 2013/01/05 Ryan Chen modify
+*
+********************************************************************************/
+//#define DEBUG
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <asm/io.h>
+#include <mach/ast_spi.h>
+#include <plat/regs-spi.h>
+
+struct ast_spi_host {
+	void __iomem		*reg;			
+	void __iomem		*buff;			
+	struct ast_spi_driver_data *spi_data;
+	struct spi_master *master;
+	struct spi_device *spi_dev;
+	struct device *dev;
+	spinlock_t				lock;
+};
+
+static inline void
+ast_spi_write(struct ast_spi_host *spi, u32 val, u32 reg)
+{
+//	dev_dbg(i2c_dev->dev, "ast_i2c_write : val: %x , reg : %x \n",val,reg);	
+	writel(val, spi->reg+ reg);
+}
+
+static inline u32
+ast_spi_read(struct ast_spi_host *spi, u32 reg)
+{
+	return readl(spi->reg + reg);
+}
+
+/* the spi->mode bits understood by this driver: */
+#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH)
+
+static int
+ast_spi_setup(struct spi_device *spi)
+{
+	struct ast_spi_host *host = (struct ast_spi_host *)spi_master_get_devdata(spi->master);
+	unsigned int         bits = spi->bits_per_word;
+	u32 spi_ctrl;
+	u32 divisor;
+	
+	int err = 0;
+	return err;
+
+	dev_dbg(host->dev, "ast_spi_setup() , cs %d\n", spi->chip_select);
+	
+	host->spi_dev = spi;
+
+	spi_ctrl = ast_spi_read(host, AST_SPI_CTRL);
+		
+	if (spi->chip_select > spi->master->num_chipselect) {
+			dev_dbg(&spi->dev,
+					"setup: invalid chipselect %u (%u defined)\n",
+					spi->chip_select, spi->master->num_chipselect);
+			return -EINVAL;
+	}
+
+	if (bits == 0)
+			bits = 8;
+	
+	if (bits < 8 || bits > 16) {
+			dev_dbg(&spi->dev,
+					"setup: invalid bits_per_word %u (8 to 16)\n",
+					bits);
+			return -EINVAL;
+	}
+
+	if (spi->mode & ~MODEBITS) {
+			dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
+					spi->mode & ~MODEBITS);
+			return -EINVAL;
+	}
+	
+	/* see notes above re chipselect */
+	if((spi->chip_select == 0) && (spi->mode & SPI_CS_HIGH)) {
+			dev_dbg(&spi->dev, "setup: can't be active-high\n");
+			return -EINVAL;
+	}
+
+	/*
+	 * Pre-new_1 chips start out at half the peripheral
+	 * bus speed.
+	 */
+	 
+	if (spi->max_speed_hz) {
+		/* Set the SPI slaves select and characteristic control register */
+		divisor = host->spi_data->get_div(spi->max_speed_hz);
+	} else {
+		/* speed zero means "as slow as possible" */
+		divisor = 15;
+	}
+
+	//TODO MASK first
+	spi_ctrl |= (divisor << 8);
+	
+	if (spi->chip_select > (spi->master->num_chipselect - 1)) {
+		dev_err(&spi->dev, "chipselect %d exceed the number of chipselect master supoort\n", spi->chip_select);
+		return -EINVAL;
+	}
+
+#if 0	
+	if (SPI_CPHA & spi->mode)
+		cpha = SPI_CPHA_1;
+	else
+		cpha = SPI_CPHA_0;
+#endif
+	
+//	if (SPI_CPOL & spi->mode) 
+//		spi_ctrl |= SPI_CPOL_1;
+//	else
+//		spi_ctrl &= ~SPI_CPOL_1;
+
+	//ISSUE : ast spi ctrl couldn't use mode 3, so fix mode 0 
+	spi_ctrl &= ~SPI_CPOL_1;
+
+
+	if (SPI_LSB_FIRST & spi->mode)
+		spi_ctrl |= SPI_LSB_FIRST_CTRL;
+	else
+		spi_ctrl &= ~SPI_LSB_FIRST_CTRL;
+
+
+	/* Configure SPI controller */
+	ast_spi_write(host, spi_ctrl, AST_SPI_CTRL);
+	
+	dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __FUNCTION__, spi->mode, spi->bits_per_word, spi->max_speed_hz);
+	return err;
+}
+
+static int ast_spi_transfer(struct spi_device *spi, struct spi_message *msg)
+{
+	struct ast_spi_host *host = (struct ast_spi_host *)spi_master_get_devdata(spi->master);
+	struct spi_transfer 	*xfer;
+	const u8 *tx_buf;
+	u8 *rx_buf;
+	
+
+	int i=0,j=0;
+
+	dev_dbg(host->dev, "new message %p submitted for %s\n",
+					msg, spi->dev.bus_id);
+
+	ast_spi_write(host, ast_spi_read(host, AST_SPI_CONFIG) | SPI_CONF_WRITE_EN, AST_SPI_CONFIG);
+//	writel( (readl(host->spi_data->ctrl_reg) | SPI_CMD_USER_MODE) | SPI_CE_INACTIVE,host->spi_data->ctrl_reg);
+	ast_spi_write(host, ast_spi_read(host, AST_SPI_CTRL) | SPI_CMD_USER_MODE, AST_SPI_CTRL);
+
+//	writel( ~SPI_CE_INACTIVE & readl(host->spi_data->ctrl_reg),host->spi_data->ctrl_reg);
+	msg->actual_length = 0;
+	msg->status = 0;
+
+
+	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+			dev_dbg(host->dev,
+					"xfer[%d] %p: width %d, len %u, tx %p/%08x, rx %p/%08x\n",
+					j, xfer,
+					xfer->bits_per_word, xfer->len,
+					xfer->tx_buf, xfer->tx_dma,
+					xfer->rx_buf, xfer->rx_dma);
+
+			//TX ----
+			if(xfer->tx_buf) {
+#if 0 				
+				if(xfer->bits_per_word == 16)
+					const u16 *tx_buf;
+				else
+					const u8 *tx_buf;
+#endif				
+				tx_buf = xfer->tx_buf;
+				for(i=0;i<xfer->len;i++) {
+					dev_dbg(host->dev, "[%d] : %x \n",i, tx_buf[i]);
+					writeb(tx_buf[i], host->buff);
+//					writeb(tx_buf[i], host->spi_data->buf_reg);
+				}
+			}
+			udelay(1);
+			//RX----
+			if(xfer->rx_buf) {
+
+				rx_buf = xfer->rx_buf;
+				dev_dbg(host->dev, "rx len [%d] \n",xfer->len );
+				for(i=0;i<xfer->len;i++) {
+//					rx_buf[i] = readb(host->spi_data->buf_reg);
+					rx_buf[i] = readb(host->buff);
+					dev_dbg(host->dev, "[%d] : %x \n",i, rx_buf[i]);
+				}
+			}
+			msg->actual_length += xfer->len;
+			j++;
+	}
+
+//	writel( SPI_CE_INACTIVE | readl(host->spi_data->ctrl_reg),host->spi_data->ctrl_reg);
+	ast_spi_write(host, (ast_spi_read(host, AST_SPI_CTRL) & ~SPI_CMD_USER_MODE) | SPI_CMD_FAST_R_MODE, AST_SPI_CTRL);
+
+	ast_spi_write(host, ast_spi_read(host, AST_SPI_CONFIG) & ~SPI_CONF_WRITE_EN, AST_SPI_CONFIG);
+
+	msg->status = 0;
+
+	spin_unlock(&host->lock);
+	msg->complete(msg->context);
+	spin_lock(&host->lock);
+
+	return 0;
+	
+}
+static void ast_spi_cleanup(struct spi_device *spi)
+{
+        struct ast_spi_host     *host = spi_master_get_devdata(spi->master);
+        unsigned long           flags;
+		dev_dbg(host->dev, "ast_spi_cleanup() \n");
+
+        spin_lock_irqsave(&host->lock, flags);
+//        if (host->stay == spi) {
+//                host->stay = NULL;
+//                cs_deactivate(host, spi);
+//        }
+        spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static int ast_spi_probe(struct platform_device *pdev)
+{
+	struct resource		*res0, *res1;
+	struct ast_spi_host *host;
+	struct spi_master *master;
+	int err;
+
+	dev_dbg(&pdev->dev, "ast_spi_probe() \n\n\n");
+
+	master = spi_alloc_master(&pdev->dev, sizeof(struct ast_spi_host));
+	if (NULL == master) {
+		dev_err(&pdev->dev, "No memory for spi_master\n");
+		err = -ENOMEM;
+		goto err_nomem;
+	}
+	host = spi_master_get_devdata(master);
+	memset(host, 0, sizeof(struct ast_spi_host));
+
+	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res0) {
+		dev_err(&pdev->dev, "cannot get IORESOURCE_MEM 0\n");		
+		err = -ENXIO;
+		goto err_no_io_res;
+	}
+
+	host->reg = ioremap(res0->start, resource_size(res0));
+	if (!host->reg) {
+		dev_err(&pdev->dev, "cannot remap register\n");
+		err = -EIO;
+		goto release_mem;
+	}	
+
+	dev_dbg(&pdev->dev, "remap phy %x, virt %x \n",(u32)res0->start, (u32)host->reg);
+
+	res1 = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (!res1) {
+		dev_err(&pdev->dev, "cannot get IORESOURCE_IO 0\n");		
+		return -ENXIO;	
+	}
+
+	host->buff = ioremap(res1->start, resource_size(res1));
+	if (!host->buff) {
+		dev_err(&pdev->dev, "cannot remap buffer \n");
+		err = -EIO;
+		goto release_mem;
+	}		
+
+	dev_dbg(&pdev->dev, "remap io phy %x, virt %x \n",(u32)res1->start, (u32)host->buff);	
+	
+	host->master = spi_master_get(master);
+	host->master->bus_num = pdev->id;
+	host->master->num_chipselect = 1;
+	host->dev = &pdev->dev;
+
+	/* Setup the state for bitbang driver */
+	host->master->setup = ast_spi_setup;
+	host->master->transfer = ast_spi_transfer;
+	host->master->cleanup = ast_spi_cleanup;
+
+	/* Find and claim our resources */
+	host->spi_data = pdev->dev.driver_data;		
+
+	platform_set_drvdata(pdev, host);
+	
+	/* Register our spi controller */
+	err = spi_register_master(host->master);
+	if (err) {
+			dev_err(&pdev->dev, "failed to register SPI master\n");
+			goto err_register;
+	}
+
+	dev_dbg(&pdev->dev, "ast_spi_probe() return \n\n\n");
+
+	return 0;
+
+err_register:
+	spi_master_put(host->master);
+	iounmap(host->reg);
+	iounmap(host->buff);	
+
+release_mem:
+	release_mem_region(res0->start, res0->end - res0->start + 1);	
+	release_mem_region(res1->start, res1->end - res1->start + 1);	
+
+err_no_io_res:
+	kfree(master);
+	kfree(host);
+	
+err_nomem:
+	return err;
+	
+}
+
+static int 
+ast_spi_remove(struct platform_device *pdev)
+{
+	struct resource 	*res0, *res1;
+	struct ast_spi_host *host = platform_get_drvdata(pdev);
+
+	dev_dbg(host->dev, "ast_spi_remove()\n");
+
+	if (!host)
+		return -1;
+
+	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res1 = platform_get_resource(pdev, IORESOURCE_IO, 0);	
+	release_mem_region(res0->start, res0->end - res0->start + 1);
+	release_mem_region(res1->start, res1->end - res1->start + 1);	
+	iounmap(host->reg);
+	iounmap(host->buff);		
+
+	platform_set_drvdata(pdev, NULL);
+	spi_unregister_master(host->master);
+	spi_master_put(host->master);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int 
+ast_spi_suspend(struct platform_device *pdev, pm_message_t msg)
+{
+	return 0;
+}
+
+static int
+ast_spi_resume(struct platform_device *pdev)
+{
+	return 0;
+}
+#else
+#define ast_spi_suspend NULL
+#define ast_spi_resume NULL
+#endif
+
+static struct platform_driver ast_spi_driver = {
+	.probe = ast_spi_probe,
+	.remove = ast_spi_remove,
+	.suspend = ast_spi_suspend,
+	.resume = ast_spi_resume,
+	.driver = {
+		.name = "ast-spi",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init
+ast_spi_init(void)
+{
+	return  platform_driver_register(&ast_spi_driver);
+}
+
+static void __exit
+ast_spi_exit(void)
+{
+	platform_driver_unregister(&ast_spi_driver);
+}
+
+subsys_initcall(ast_spi_init);
+//module_init(ast_spi_init);
+module_exit(ast_spi_exit);
+
+MODULE_DESCRIPTION("AST SPI Driver");
+MODULE_AUTHOR("Ryan Chen");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/fmc_spi.c b/drivers/spi/fmc_spi.c
new file mode 100644
index 0000000..ccc0d1c
--- /dev/null
+++ b/drivers/spi/fmc_spi.c
@@ -0,0 +1,436 @@
+/********************************************************************************
+* File Name     : driver/spi/ast-spi.c
+* Author        : Ryan Chen
+* Description   : ASPEED SPI host driver
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+*   History      :
+*	1. 2012/10/20 Ryan Chen create this file
+*	1. 2013/01/05 Ryan Chen modify
+*
+********************************************************************************/
+//#define DEBUG
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <asm/io.h>
+#include <mach/ast_spi.h>
+#include <plat/regs-spi.h>
+
+//IN FMC SPI always control offset 0x00
+
+struct fmc_spi_host {
+	void __iomem		*reg;			
+	void __iomem		*buff;			
+	struct ast_spi_driver_data *spi_data;
+	struct spi_master *master;
+	struct spi_device *spi_dev;
+	struct device *dev;
+	spinlock_t				lock;
+};
+
+static inline void
+fmc_spi_write(struct fmc_spi_host *host, u32 val, u32 reg)
+{
+//	printk("write : val: %x , offset : %x \n",val, reg);	
+	writel(val, host->reg + reg);
+}
+
+static inline u32
+fmc_spi_read(struct fmc_spi_host *host, u32 reg)
+{
+	return readl(host->reg + reg);
+}
+
+/* the spi->mode bits understood by this driver: */
+#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH)
+
+static int
+fmc_spi_setup(struct spi_device *spi)
+{
+	struct fmc_spi_host *host = (struct fmc_spi_host *)spi_master_get_devdata(spi->master);
+	unsigned int         bits = spi->bits_per_word;
+	u32 spi_ctrl;
+	u32 divisor;
+	
+	int err = 0;
+	dev_dbg(host->dev, "fmc_spi_setup() ======================>>\n");	
+
+
+	dev_dbg(host->dev, "fmc_spi_setup() ======================>>\n");
+	
+	host->spi_dev = spi;
+
+	spi_ctrl = fmc_spi_read(host, 0x00);
+//	printk("trl : %x \n",spi_ctrl);
+		
+	if (spi->chip_select > spi->master->num_chipselect) {
+			dev_dbg(&spi->dev,
+					"setup: invalid chipselect %u (%u defined)\n",
+					spi->chip_select, spi->master->num_chipselect);
+			return -EINVAL;
+	}
+
+	if (bits == 0)
+			bits = 8;
+	
+	if (bits < 8 || bits > 16) {
+			dev_dbg(&spi->dev,
+					"setup: invalid bits_per_word %u (8 to 16)\n",
+					bits);
+			return -EINVAL;
+	}
+
+	if (spi->mode & ~MODEBITS) {
+			dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
+					spi->mode & ~MODEBITS);
+			return -EINVAL;
+	}
+	
+	/* see notes above re chipselect */
+	if((spi->chip_select == 0) && (spi->mode & SPI_CS_HIGH)) {
+			dev_dbg(&spi->dev, "setup: can't be active-high\n");
+			return -EINVAL;
+	}
+
+	/*
+	 * Pre-new_1 chips start out at half the peripheral
+	 * bus speed.
+	 */
+	 
+	if (spi->max_speed_hz) {
+		/* Set the SPI slaves select and characteristic control register */
+		divisor = host->spi_data->get_div(spi->max_speed_hz);
+	} else {
+		/* speed zero means "as slow as possible" */
+		divisor = 15;
+	}
+
+	spi_ctrl &= ~SPI_CLK_DIV_MASK;
+//	printk("set div %x \n",divisor);
+	//TODO MASK first
+	spi_ctrl |= SPI_CLK_DIV(divisor);
+	
+	if (spi->chip_select > (spi->master->num_chipselect - 1)) {
+		dev_err(&spi->dev, "chipselect %d exceed the number of chipselect master supoort\n", spi->chip_select);
+		return -EINVAL;
+	}
+
+#if 0	
+	if (SPI_CPHA & spi->mode)
+		cpha = SPI_CPHA_1;
+	else
+		cpha = SPI_CPHA_0;
+#endif
+	
+//	if (SPI_CPOL & spi->mode) 
+//		spi_ctrl |= SPI_CPOL_1;
+//	else
+//		spi_ctrl &= ~SPI_CPOL_1;
+
+	//ISSUE : ast spi ctrl couldn't use mode 3, so fix mode 0 
+	spi_ctrl &= ~SPI_CPOL_1;
+
+
+	if (SPI_LSB_FIRST & spi->mode)
+		spi_ctrl |= SPI_LSB_FIRST_CTRL;
+	else
+		spi_ctrl &= ~SPI_LSB_FIRST_CTRL;
+
+
+	/* Configure SPI controller */
+	fmc_spi_write(host, spi_ctrl, 0x00);
+	
+	dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __FUNCTION__, spi->mode, spi->bits_per_word, spi->max_speed_hz);
+	return err;
+}
+
+static int fmc_spi_transfer(struct spi_device *spi, struct spi_message *msg)
+{
+	struct fmc_spi_host *host = (struct fmc_spi_host *)spi_master_get_devdata(spi->master);
+	struct spi_transfer 	*xfer;
+	const u8 *tx_buf;
+	u8 *rx_buf;
+	unsigned long		flags;
+
+	int i=0,j=0;
+
+	dev_dbg(host->dev, "new message %p submitted for %s \n",
+					msg, dev_name(&spi->dev));
+	
+	spin_lock_irqsave(&host->lock, flags);
+//	writel( (readl(host->spi_data->ctrl_reg) | SPI_CMD_USER_MODE) | SPI_CE_INACTIVE,host->spi_data->ctrl_reg);
+	fmc_spi_write(host, fmc_spi_read(host, 0x00) | SPI_CMD_USER_MODE, 0x00);
+	msg->actual_length = 0;
+	msg->status = 0;
+	
+//	writel( ~SPI_CE_INACTIVE & readl(host->spi_data->ctrl_reg),host->spi_data->ctrl_reg);
+
+	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+			dev_dbg(host->dev,
+					"xfer[%d] %p: width %d, len %u, tx %p/%08x, rx %p/%08x\n",
+					j, xfer,
+					xfer->bits_per_word, xfer->len,
+					xfer->tx_buf, xfer->tx_dma,
+					xfer->rx_buf, xfer->rx_dma);
+
+		tx_buf = xfer->tx_buf;
+		rx_buf = xfer->rx_buf;
+
+
+		if(tx_buf != 0) {
+#if 0			
+			printk("tx : ");
+			if(xfer->len > 10) {
+				for(i=0;i<10;i++) 
+					printk("%x ",tx_buf[i]);				
+			} else {
+				for(i=0;i<xfer->len;i++) 
+					printk("%x ",tx_buf[i]);
+			}
+			printk("\n");
+#endif
+			for(i=0;i<xfer->len;i++) {
+				writeb(tx_buf[i], host->buff);
+			}
+		}
+		//Issue need clarify 
+		udelay(1);
+		if(rx_buf != 0) {
+			for(i=0;i<xfer->len;i++) {
+				rx_buf[i] = readb(host->buff);
+			}
+#if 0			
+			printk("rx : ");
+			if(xfer->len > 10) {
+				for(i=0;i<10;i++) 
+					printk(" %x",rx_buf[i]);
+			} else {
+				for(i=0;i<xfer->len;i++) 
+					printk(" %x",rx_buf[i]);
+			}
+			printk("\n");
+#endif			
+		}
+		dev_dbg(host->dev,"old msg->actual_length %d , +len %d \n",msg->actual_length, xfer->len);
+		msg->actual_length += xfer->len;
+		dev_dbg(host->dev,"new msg->actual_length %d \n",msg->actual_length);
+//		j++;
+
+	}
+
+//	writel( SPI_CE_INACTIVE | readl(host->spi_data->ctrl_reg),host->spi_data->ctrl_reg);
+	fmc_spi_write(host, (fmc_spi_read(host, 0x00) & ~SPI_CMD_USER_MODE), 0x00);
+	msg->status = 0;
+
+	msg->complete(msg->context);
+
+//	spin_unlock(&host->lock);
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	
+	
+
+	return 0;
+	
+}
+static void fmc_spi_cleanup(struct spi_device *spi)
+{
+        struct fmc_spi_host     *host = spi_master_get_devdata(spi->master);
+        unsigned long           flags;
+		dev_dbg(host->dev, "fmc_spi_cleanup() \n");
+
+        spin_lock_irqsave(&host->lock, flags);
+//        if (host->stay == spi) {
+//                host->stay = NULL;
+//                cs_deactivate(host, spi);
+//        }
+        spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static int fmc_spi_probe(struct platform_device *pdev)
+{
+	struct resource		*res0, *res1=0;
+	struct fmc_spi_host *host;
+	struct spi_master *master;
+	int err;
+
+	dev_dbg(&pdev->dev, "fmc_spi_probe() \n\n\n");
+
+	master = spi_alloc_master(&pdev->dev, sizeof(struct fmc_spi_host));
+	if (NULL == master) {
+		dev_err(&pdev->dev, "No memory for spi_master\n");
+		err = -ENOMEM;
+		goto err_nomem;
+	}
+	host = spi_master_get_devdata(master);
+	memset(host, 0, sizeof(struct fmc_spi_host));
+
+	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res0) {
+		dev_err(&pdev->dev, "cannot get IORESOURCE_MEM 0\n");		
+		err = -ENXIO;
+		goto err_no_io_res;
+	}
+
+	host->reg = ioremap(res0->start, resource_size(res0));
+	if (!host->reg) {
+		dev_err(&pdev->dev, "cannot remap register\n");
+		err = -EIO;
+		goto release_mem;
+	}	
+
+	dev_dbg(&pdev->dev, "remap phy %x, virt %x \n",(u32)res0->start, (u32)host->reg);
+
+	res1 = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (!res1) {
+		dev_err(&pdev->dev, "cannot get IORESOURCE_IO 0\n");		
+		return -ENXIO;	
+	}
+
+	host->buff = ioremap(res1->start, resource_size(res1));
+	if (!host->buff) {
+		dev_err(&pdev->dev, "cannot remap buffer \n");
+		err = -EIO;
+		goto release_mem;
+	}		
+
+	dev_dbg(&pdev->dev, "remap io phy %x, virt %x \n",(u32)res1->start, (u32)host->buff);	
+	
+	host->master = spi_master_get(master);
+	host->master->bus_num = pdev->id;
+	host->master->num_chipselect = 1;
+	host->dev = &pdev->dev;
+
+	/* Setup the state for bitbang driver */
+	host->master->setup = fmc_spi_setup;
+	host->master->transfer = fmc_spi_transfer;
+	host->master->cleanup = fmc_spi_cleanup;
+
+	/* Find and claim our resources */
+	host->spi_data = pdev->dev.platform_data;		
+
+	platform_set_drvdata(pdev, host);
+	
+	/* Register our spi controller */
+	err = spi_register_master(host->master);
+	if (err) {
+			dev_err(&pdev->dev, "failed to register SPI master\n");
+			goto err_register;
+	}
+
+	dev_dbg(&pdev->dev, "fmc_spi_probe() return \n\n\n");
+
+	return 0;
+
+err_register:
+	spi_master_put(host->master);
+	iounmap(host->reg);
+	iounmap(host->buff);	
+
+release_mem:
+	release_mem_region(res0->start, res0->end - res0->start + 1);	
+	release_mem_region(res1->start, res1->end - res1->start + 1);	
+
+err_no_io_res:
+	kfree(master);
+	kfree(host);
+	
+err_nomem:
+	return err;
+	
+}
+
+static int 
+fmc_spi_remove(struct platform_device *pdev)
+{
+	struct resource 	*res0, *res1;
+	struct fmc_spi_host *host = platform_get_drvdata(pdev);
+
+	dev_dbg(host->dev, "fmc_spi_remove()\n");
+
+	if (!host)
+		return -1;
+
+	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res1 = platform_get_resource(pdev, IORESOURCE_IO, 0);	
+	release_mem_region(res0->start, res0->end - res0->start + 1);
+	release_mem_region(res1->start, res1->end - res1->start + 1);	
+	iounmap(host->reg);
+	iounmap(host->buff);		
+
+	platform_set_drvdata(pdev, NULL);
+	spi_unregister_master(host->master);
+	spi_master_put(host->master);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int 
+fmc_spi_suspend(struct platform_device *pdev, pm_message_t msg)
+{
+	return 0;
+}
+
+static int
+fmc_spi_resume(struct platform_device *pdev)
+{
+	return 0;
+}
+#else
+#define fmc_spi_suspend NULL
+#define fmc_spi_resume NULL
+#endif
+
+static struct platform_driver fmc_spi_driver = {
+	.probe = fmc_spi_probe,
+	.remove = fmc_spi_remove,
+	.suspend = fmc_spi_suspend,
+	.resume = fmc_spi_resume,
+	.driver = {
+		.name = "fmc-spi",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init
+fmc_spi_init(void)
+{
+	return  platform_driver_register(&fmc_spi_driver);
+}
+
+static void __exit
+fmc_spi_exit(void)
+{
+	platform_driver_unregister(&fmc_spi_driver);
+}
+
+subsys_initcall(fmc_spi_init);
+//module_init(fmc_spi_init);
+module_exit(fmc_spi_exit);
+
+MODULE_DESCRIPTION("FMC SPI Driver");
+MODULE_AUTHOR("Ryan Chen");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 3734dc9..ec88fc7 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -652,54 +652,61 @@ static u8	*buf;
  * Performance-sensitive or bulk transfer code should instead use
  * spi_{async,sync}() calls with dma-safe buffers.
  */
-int spi_write_then_read(struct spi_device *spi,
-		const u8 *txbuf, unsigned n_tx,
-		u8 *rxbuf, unsigned n_rx)
-{
-	static DEFINE_MUTEX(lock);
-
-	int			status;
-	struct spi_message	message;
-	struct spi_transfer	x;
-	u8			*local_buf;
-
-	/* Use preallocated DMA-safe buffer.  We can't avoid copying here,
-	 * (as a pure convenience thing), but we can keep heap costs
-	 * out of the hot path ...
-	 */
-	if ((n_tx + n_rx) > SPI_BUFSIZ)
-		return -EINVAL;
-
-	spi_message_init(&message);
-	memset(&x, 0, sizeof x);
-	x.len = n_tx + n_rx;
-	spi_message_add_tail(&x, &message);
-
-	/* ... unless someone else is using the pre-allocated buffer */
-	if (!mutex_trylock(&lock)) {
-		local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
-		if (!local_buf)
-			return -ENOMEM;
-	} else
-		local_buf = buf;
-
-	memcpy(local_buf, txbuf, n_tx);
-	x.tx_buf = local_buf;
-	x.rx_buf = local_buf;
-
-	/* do the i/o */
-	status = spi_sync(spi, &message);
-	if (status == 0)
-		memcpy(rxbuf, x.rx_buf + n_tx, n_rx);
-
-	if (x.tx_buf == buf)
-		mutex_unlock(&lock);
-	else
-		kfree(local_buf);
+	int spi_write_then_read(struct spi_device *spi,
+			const u8 *txbuf, unsigned n_tx,
+			u8 *rxbuf, unsigned n_rx)
+	{
+		static DEFINE_MUTEX(lock);
+	
+		int 		status;
+		struct spi_message	message;
+		struct spi_transfer x[2];
+		u8			*local_buf;
+	
+		/* Use preallocated DMA-safe buffer.  We can't avoid copying here,
+		 * (as a pure convenience thing), but we can keep heap costs
+		 * out of the hot path ...
+		 */
+		if ((n_tx + n_rx) > SPI_BUFSIZ)
+			return -EINVAL;
+	
+		spi_message_init(&message);
+		memset(x, 0, sizeof x);
+		if (n_tx) {
+			x[0].len = n_tx;
+			spi_message_add_tail(&x[0], &message);
+		}
+		if (n_rx) {
+			x[1].len = n_rx;
+			spi_message_add_tail(&x[1], &message);
+		}
+	
+		/* ... unless someone else is using the pre-allocated buffer */
+		if (!mutex_trylock(&lock)) {
+			local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
+			if (!local_buf)
+				return -ENOMEM;
+		} else
+			local_buf = buf;
+	
+		memcpy(local_buf, txbuf, n_tx);
+		x[0].tx_buf = local_buf;
+		x[1].rx_buf = local_buf + n_tx;
+	
+		/* do the i/o */
+		status = spi_sync(spi, &message);
+		if (status == 0)
+			memcpy(rxbuf, x[1].rx_buf, n_rx);
+	
+		if (x[0].tx_buf == buf)
+			mutex_unlock(&lock);
+		else
+			kfree(local_buf);
+	
+		return status;
+	}
+	EXPORT_SYMBOL_GPL(spi_write_then_read);
 
-	return status;
-}
-EXPORT_SYMBOL_GPL(spi_write_then_read);
 
 /*-------------------------------------------------------------------------*/
 
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 289d81a..2cba323 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -56,6 +56,7 @@ config USB_ARCH_HAS_EHCI
 	default y if PPC_83xx
 	default y if SOC_AU1200
 	default y if ARCH_IXP4XX
+	default y if ARCH_ASPEED
 	default PCI
 
 # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
@@ -102,6 +103,8 @@ source "drivers/usb/wusbcore/Kconfig"
 
 source "drivers/usb/host/Kconfig"
 
+source "drivers/usb/astuhci/Kconfig"
+
 source "drivers/usb/musb/Kconfig"
 
 source "drivers/usb/class/Kconfig"
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 8b7c419..f6f180c 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -8,6 +8,8 @@ obj-$(CONFIG_USB)		+= core/
 
 obj-$(CONFIG_USB_MON)		+= mon/
 
+obj-$(CONFIG_AST_USB_UHCI_HCD)	+= astuhci/
+
 obj-$(CONFIG_PCI)		+= host/
 obj-$(CONFIG_USB_EHCI_HCD)	+= host/
 obj-$(CONFIG_USB_ISP116X_HCD)	+= host/
diff --git a/drivers/usb/astuhci/Kconfig b/drivers/usb/astuhci/Kconfig
new file mode 100644
index 0000000..69c6d79
--- /dev/null
+++ b/drivers/usb/astuhci/Kconfig
@@ -0,0 +1,56 @@
+#
+# USB Host Controller Drivers
+#
+comment "AST USB Drivers"
+	depends on USB
+
+
+config AST_USB_UHCI_HCD
+	tristate "AST UHCI (USB 1.1) support"
+	depends on USB
+	---help---
+	  The AST Universal Host Controller Interface (UHCI) is standard for 
+	  USB 1.1 host controller hardware. It is an embedded HC based on AMBA bus.
+	  You may want to read <file:Documentation/usb/uhci.txt>.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called uhci-hcd.
+
+choice
+	prompt "Config AST USB UHCI Number of Ports"
+	default AST_USB_UHCI_MULTIPORT_4
+
+config AST_USB_UHCI_MULTIPORT_1
+	bool "AST UHCI support 1 ports"
+	depends on AST_USB_UHCI_HCD
+
+config AST_USB_UHCI_MULTIPORT_2
+	bool "AST UHCI support 2 ports"
+	depends on AST_USB_UHCI_HCD
+
+config AST_USB_UHCI_MULTIPORT_4
+	bool "AST UHCI support 4 ports"
+	depends on AST_USB_UHCI_HCD
+
+endchoice
+
+config USB_EHCI_SPLIT_ISO
+	bool "Full speed ISO transactions (EXPERIMENTAL)"
+	depends on USB_EHCI_HCD
+	default n
+	---help---
+	  This code is new and hasn't been used with many different
+	  EHCI or USB 2.0 transaction translator implementations.
+	  It should work for ISO-OUT transfers, like audio.
+
+config USB_EHCI_ROOT_HUB_TT
+	bool "Root Hub Transaction Translators (EXPERIMENTAL)"
+	depends on USB_EHCI_HCD
+	---help---
+	  Some EHCI chips have vendor-specific extensions to integrate
+	  transaction translators, so that no OHCI or UHCI companion
+	  controller is needed.  It's safe to say "y" even if your
+	  controller doesn't support this feature.
+
+	  This supports the EHCI implementation from TransDimension Inc.
+
diff --git a/drivers/usb/astuhci/Makefile b/drivers/usb/astuhci/Makefile
new file mode 100644
index 0000000..6b858f7
--- /dev/null
+++ b/drivers/usb/astuhci/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for USB Host Controller Drivers
+#
+
+ifeq ($(CONFIG_USB_DEBUG),y)
+	EXTRA_CFLAGS		+= -DDEBUG
+endif
+
+
+obj-$(CONFIG_AST_USB_UHCI_HCD)	+= uhci-hcd.o
diff --git a/drivers/usb/astuhci/uhci-debug.c b/drivers/usb/astuhci/uhci-debug.c
new file mode 100644
index 0000000..c617644
--- /dev/null
+++ b/drivers/usb/astuhci/uhci-debug.c
@@ -0,0 +1,595 @@
+/********************************************************************************
+* File Name     : uhci-debug.c
+* 
+* port from uhci-debug.c
+* 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/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/smp_lock.h>
+#include <asm/io.h>
+
+#include "uhci-hcd.h"
+
+#define uhci_debug_operations (* (const struct file_operations *) NULL)
+static struct dentry *uhci_debugfs_root;
+
+#ifdef DEBUG
+
+/* Handle REALLY large printks so we don't overflow buffers */
+static void lprintk(char *buf)
+{
+	char *p;
+
+	/* Just write one line at a time */
+	while (buf) {
+		p = strchr(buf, '\n');
+		if (p)
+			*p = 0;
+		printk(KERN_DEBUG "%s\n", buf);
+		buf = p;
+		if (buf)
+			buf++;
+	}
+}
+
+static int uhci_show_td(struct uhci_td *td, char *buf, int len, int space)
+{
+	char *out = buf;
+	char *spid;
+	u32 status, token;
+
+	/* Try to make sure there's enough memory */
+	if (len < 160)
+		return 0;
+
+	status = td_status(td);
+	out += sprintf(out, "%*s[%p] link (%08x) ", space, "", td, le32_to_cpu(td->link));
+	out += sprintf(out, "e%d %s%s%s%s%s%s%s%s%s%sLength=%x ",
+		((status >> 27) & 3),
+		(status & TD_CTRL_SPD) ?      "SPD " : "",
+		(status & TD_CTRL_LS) ?       "LS " : "",
+		(status & TD_CTRL_IOC) ?      "IOC " : "",
+		(status & TD_CTRL_ACTIVE) ?   "Active " : "",
+		(status & TD_CTRL_STALLED) ?  "Stalled " : "",
+		(status & TD_CTRL_DBUFERR) ?  "DataBufErr " : "",
+		(status & TD_CTRL_BABBLE) ?   "Babble " : "",
+		(status & TD_CTRL_NAK) ?      "NAK " : "",
+		(status & TD_CTRL_CRCTIMEO) ? "CRC/Timeo " : "",
+		(status & TD_CTRL_BITSTUFF) ? "BitStuff " : "",
+		status & 0x7ff);
+
+	token = td_token(td);
+	switch (uhci_packetid(token)) {
+		case USB_PID_SETUP:
+			spid = "SETUP";
+			break;
+		case USB_PID_OUT:
+			spid = "OUT";
+			break;
+		case USB_PID_IN:
+			spid = "IN";
+			break;
+		default:
+			spid = "?";
+			break;
+	}
+
+	out += sprintf(out, "MaxLen=%x DT%d EndPt=%x Dev=%x, PID=%x(%s) ",
+		token >> 21,
+		((token >> 19) & 1),
+		(token >> 15) & 15,
+		(token >> 8) & 127,
+		(token & 0xff),
+		spid);
+	out += sprintf(out, "(buf=%08x)\n", le32_to_cpu(td->buffer));
+
+	return out - buf;
+}
+
+static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space)
+{
+	char *out = buf;
+	struct uhci_td *td;
+	int i, nactive, ninactive;
+	char *ptype;
+
+	if (len < 200)
+		return 0;
+
+	out += sprintf(out, "urb_priv [%p] ", urbp);
+	out += sprintf(out, "urb [%p] ", urbp->urb);
+	out += sprintf(out, "qh [%p] ", urbp->qh);
+	out += sprintf(out, "Dev=%d ", usb_pipedevice(urbp->urb->pipe));
+	out += sprintf(out, "EP=%x(%s) ", usb_pipeendpoint(urbp->urb->pipe),
+			(usb_pipein(urbp->urb->pipe) ? "IN" : "OUT"));
+
+	switch (usb_pipetype(urbp->urb->pipe)) {
+	case PIPE_ISOCHRONOUS: ptype = "ISO"; break;
+	case PIPE_INTERRUPT: ptype = "INT"; break;
+	case PIPE_BULK: ptype = "BLK"; break;
+	default:
+	case PIPE_CONTROL: ptype = "CTL"; break;
+	}
+
+	out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : ""));
+	out += sprintf(out, " Actlen=%d", urbp->urb->actual_length);
+
+	if (urbp->urb->unlinked)
+		out += sprintf(out, " Unlinked=%d", urbp->urb->unlinked);
+	out += sprintf(out, "\n");
+
+	i = nactive = ninactive = 0;
+	list_for_each_entry(td, &urbp->td_list, list) {
+		if (urbp->qh->type != USB_ENDPOINT_XFER_ISOC &&
+				(++i <= 10 || debug > 2)) {
+			out += sprintf(out, "%*s%d: ", space + 2, "", i);
+			out += uhci_show_td(td, out, len - (out - buf), 0);
+		} else {
+			if (td_status(td) & TD_CTRL_ACTIVE)
+				++nactive;
+			else
+				++ninactive;
+		}
+	}
+	if (nactive + ninactive > 0)
+		out += sprintf(out, "%*s[skipped %d inactive and %d active "
+				"TDs]\n",
+				space, "", ninactive, nactive);
+
+	return out - buf;
+}
+
+static int uhci_show_qh(struct uhci_hcd *uhci,
+		struct uhci_qh *qh, char *buf, int len, int space)
+{
+	char *out = buf;
+	int i, nurbs;
+	__le32 element = qh_element(qh);
+	char *qtype;
+
+	/* Try to make sure there's enough memory */
+	if (len < 80 * 7)
+		return 0;
+
+	switch (qh->type) {
+	case USB_ENDPOINT_XFER_ISOC: qtype = "ISO"; break;
+	case USB_ENDPOINT_XFER_INT: qtype = "INT"; break;
+	case USB_ENDPOINT_XFER_BULK: qtype = "BLK"; break;
+	case USB_ENDPOINT_XFER_CONTROL: qtype = "CTL"; break;
+	default: qtype = "Skel" ; break;
+	}
+
+	out += sprintf(out, "%*s[%p] %s QH link (%08x) element (%08x)\n",
+			space, "", qh, qtype,
+			le32_to_cpu(qh->link), le32_to_cpu(element));
+	if (qh->type == USB_ENDPOINT_XFER_ISOC)
+		out += sprintf(out, "%*s    period %d phase %d load %d us, "
+				"frame %x desc [%p]\n",
+				space, "", qh->period, qh->phase, qh->load,
+				qh->iso_frame, qh->iso_packet_desc);
+	else if (qh->type == USB_ENDPOINT_XFER_INT)
+		out += sprintf(out, "%*s    period %d phase %d load %d us\n",
+				space, "", qh->period, qh->phase, qh->load);
+
+	if (element & UHCI_PTR_QH)
+		out += sprintf(out, "%*s  Element points to QH (bug?)\n", space, "");
+
+	if (element & UHCI_PTR_DEPTH)
+		out += sprintf(out, "%*s  Depth traverse\n", space, "");
+
+	if (element & cpu_to_le32(8))
+		out += sprintf(out, "%*s  Bit 3 set (bug?)\n", space, "");
+
+	if (!(element & ~(UHCI_PTR_QH | UHCI_PTR_DEPTH)))
+		out += sprintf(out, "%*s  Element is NULL (bug?)\n", space, "");
+
+	if (list_empty(&qh->queue)) {
+		out += sprintf(out, "%*s  queue is empty\n", space, "");
+		if (qh == uhci->skel_async_qh)
+			out += uhci_show_td(uhci->term_td, out,
+					len - (out - buf), 0);
+	} else {
+		struct urb_priv *urbp = list_entry(qh->queue.next,
+				struct urb_priv, node);
+		struct uhci_td *td = list_entry(urbp->td_list.next,
+				struct uhci_td, list);
+
+		if (element != LINK_TO_TD(td))
+			out += sprintf(out, "%*s Element != First TD\n",
+					space, "");
+		i = nurbs = 0;
+		list_for_each_entry(urbp, &qh->queue, node) {
+			if (++i <= 10)
+				out += uhci_show_urbp(urbp, out,
+						len - (out - buf), space + 2);
+			else
+				++nurbs;
+		}
+		if (nurbs > 0)
+			out += sprintf(out, "%*s Skipped %d URBs\n",
+					space, "", nurbs);
+	}
+
+	if (qh->dummy_td) {
+		out += sprintf(out, "%*s  Dummy TD\n", space, "");
+		out += uhci_show_td(qh->dummy_td, out, len - (out - buf), 0);
+	}
+
+	return out - buf;
+}
+
+static int uhci_show_sc(int port, unsigned short status, char *buf, int len)
+{
+	char *out = buf;
+
+	/* Try to make sure there's enough memory */
+	if (len < 160)
+		return 0;
+
+	out += sprintf(out, "  stat%d     =     %04x  %s%s%s%s%s%s%s%s%s%s\n",
+		port,
+		status,
+		(status & USBPORTSC_SUSP) ?	" Suspend" : "",
+		(status & USBPORTSC_OCC) ?	" OverCurrentChange" : "",
+		(status & USBPORTSC_OC) ?	" OverCurrent" : "",
+		(status & USBPORTSC_PR) ?	" Reset" : "",
+		(status & USBPORTSC_LSDA) ?	" LowSpeed" : "",
+		(status & USBPORTSC_RD) ?	" ResumeDetect" : "",
+		(status & USBPORTSC_PEC) ?	" EnableChange" : "",
+		(status & USBPORTSC_PE) ?	" Enabled" : "",
+		(status & USBPORTSC_CSC) ?	" ConnectChange" : "",
+		(status & USBPORTSC_CCS) ?	" Connected" : "");
+
+	return out - buf;
+}
+
+static int uhci_show_root_hub_state(struct uhci_hcd *uhci, char *buf, int len)
+{
+	char *out = buf;
+	char *rh_state;
+
+	/* Try to make sure there's enough memory */
+	if (len < 60)
+		return 0;
+
+	switch (uhci->rh_state) {
+	    case UHCI_RH_RESET:
+		rh_state = "reset";		break;
+	    case UHCI_RH_SUSPENDED:
+		rh_state = "suspended";		break;
+	    case UHCI_RH_AUTO_STOPPED:
+		rh_state = "auto-stopped";	break;
+	    case UHCI_RH_RESUMING:
+		rh_state = "resuming";		break;
+	    case UHCI_RH_SUSPENDING:
+		rh_state = "suspending";	break;
+	    case UHCI_RH_RUNNING:
+		rh_state = "running";		break;
+	    case UHCI_RH_RUNNING_NODEVS:
+		rh_state = "running, no devs";	break;
+	    default:
+		rh_state = "?";			break;
+	}
+	out += sprintf(out, "Root-hub state: %s   FSBR: %d\n",
+			rh_state, uhci->fsbr_is_on);
+	return out - buf;
+}
+
+static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len)
+{
+	char *out = buf;
+	unsigned long io_addr = uhci->io_addr;
+	unsigned short usbcmd, usbstat, usbint, usbfrnum;
+	unsigned int flbaseadd;
+	unsigned char sof;
+	unsigned short portsc1, portsc2;
+
+	/* Try to make sure there's enough memory */
+	if (len < 80 * 9)
+		return 0;
+
+	usbcmd    = inw(io_addr + 0);
+	usbstat   = inw(io_addr + 2);
+	usbint    = inw(io_addr + 4);
+	usbfrnum  = inw(io_addr + 6);
+	flbaseadd = inl(io_addr + 8);
+	sof       = inb(io_addr + 12);
+	portsc1   = inw(io_addr + 16);
+	portsc2   = inw(io_addr + 18);
+
+	out += sprintf(out, "  usbcmd    =     %04x   %s%s%s%s%s%s%s%s\n",
+		usbcmd,
+		(usbcmd & USBCMD_MAXP) ?    "Maxp64 " : "Maxp32 ",
+		(usbcmd & USBCMD_CF) ?      "CF " : "",
+		(usbcmd & USBCMD_SWDBG) ?   "SWDBG " : "",
+		(usbcmd & USBCMD_FGR) ?     "FGR " : "",
+		(usbcmd & USBCMD_EGSM) ?    "EGSM " : "",
+		(usbcmd & USBCMD_GRESET) ?  "GRESET " : "",
+		(usbcmd & USBCMD_HCRESET) ? "HCRESET " : "",
+		(usbcmd & USBCMD_RS) ?      "RS " : "");
+
+	out += sprintf(out, "  usbstat   =     %04x   %s%s%s%s%s%s\n",
+		usbstat,
+		(usbstat & USBSTS_HCH) ?    "HCHalted " : "",
+		(usbstat & USBSTS_HCPE) ?   "HostControllerProcessError " : "",
+		(usbstat & USBSTS_HSE) ?    "HostSystemError " : "",
+		(usbstat & USBSTS_RD) ?     "ResumeDetect " : "",
+		(usbstat & USBSTS_ERROR) ?  "USBError " : "",
+		(usbstat & USBSTS_USBINT) ? "USBINT " : "");
+
+	out += sprintf(out, "  usbint    =     %04x\n", usbint);
+	out += sprintf(out, "  usbfrnum  =   (%d)%03x\n", (usbfrnum >> 10) & 1,
+		0xfff & (4*(unsigned int)usbfrnum));
+	out += sprintf(out, "  flbaseadd = %08x\n", flbaseadd);
+	out += sprintf(out, "  sof       =       %02x\n", sof);
+	out += uhci_show_sc(1, portsc1, out, len - (out - buf));
+	out += uhci_show_sc(2, portsc2, out, len - (out - buf));
+	out += sprintf(out, "Most recent frame: %x (%d)   "
+			"Last ISO frame: %x (%d)\n",
+			uhci->frame_number, uhci->frame_number & 1023,
+			uhci->last_iso_frame, uhci->last_iso_frame & 1023);
+
+	return out - buf;
+}
+
+static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
+{
+	char *out = buf;
+	int i, j;
+	struct uhci_qh *qh;
+	struct uhci_td *td;
+	struct list_head *tmp, *head;
+	int nframes, nerrs;
+	__le32 link;
+	__le32 fsbr_link;
+
+	static const char * const qh_names[] = {
+		"unlink", "iso", "int128", "int64", "int32", "int16",
+		"int8", "int4", "int2", "async", "term"
+	};
+
+	out += uhci_show_root_hub_state(uhci, out, len - (out - buf));
+	out += sprintf(out, "HC status\n");
+	out += uhci_show_status(uhci, out, len - (out - buf));
+
+	out += sprintf(out, "Periodic load table\n");
+	for (i = 0; i < MAX_PHASE; ++i) {
+		out += sprintf(out, "\t%d", uhci->load[i]);
+		if (i % 8 == 7)
+			*out++ = '\n';
+	}
+	out += sprintf(out, "Total: %d, #INT: %d, #ISO: %d\n",
+			uhci->total_load,
+			uhci_to_hcd(uhci)->self.bandwidth_int_reqs,
+			uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs);
+	if (debug <= 1)
+		return out - buf;
+
+	out += sprintf(out, "Frame List\n");
+	nframes = 10;
+	nerrs = 0;
+	for (i = 0; i < UHCI_NUMFRAMES; ++i) {
+		__le32 qh_dma;
+
+		j = 0;
+		td = uhci->frame_cpu[i];
+		link = uhci->frame[i];
+		if (!td)
+			goto check_link;
+
+		if (nframes > 0) {
+			out += sprintf(out, "- Frame %d -> (%08x)\n",
+					i, le32_to_cpu(link));
+			j = 1;
+		}
+
+		head = &td->fl_list;
+		tmp = head;
+		do {
+			td = list_entry(tmp, struct uhci_td, fl_list);
+			tmp = tmp->next;
+			if (link != LINK_TO_TD(td)) {
+				if (nframes > 0)
+					out += sprintf(out, "    link does "
+						"not match list entry!\n");
+				else
+					++nerrs;
+			}
+			if (nframes > 0)
+				out += uhci_show_td(td, out,
+						len - (out - buf), 4);
+			link = td->link;
+		} while (tmp != head);
+
+check_link:
+		qh_dma = uhci_frame_skel_link(uhci, i);
+		if (link != qh_dma) {
+			if (nframes > 0) {
+				if (!j) {
+					out += sprintf(out,
+						"- Frame %d -> (%08x)\n",
+						i, le32_to_cpu(link));
+					j = 1;
+				}
+				out += sprintf(out, "   link does not match "
+					"QH (%08x)!\n", le32_to_cpu(qh_dma));
+			} else
+				++nerrs;
+		}
+		nframes -= j;
+	}
+	if (nerrs > 0)
+		out += sprintf(out, "Skipped %d bad links\n", nerrs);
+
+	out += sprintf(out, "Skeleton QHs\n");
+
+	fsbr_link = 0;
+	for (i = 0; i < UHCI_NUM_SKELQH; ++i) {
+		int cnt = 0;
+
+		qh = uhci->skelqh[i];
+		out += sprintf(out, "- skel_%s_qh\n", qh_names[i]); \
+		out += uhci_show_qh(uhci, qh, out, len - (out - buf), 4);
+
+		/* Last QH is the Terminating QH, it's different */
+		if (i == SKEL_TERM) {
+			if (qh_element(qh) != LINK_TO_TD(uhci->term_td))
+				out += sprintf(out, "    skel_term_qh element is not set to term_td!\n");
+			link = fsbr_link;
+			if (!link)
+				link = LINK_TO_QH(uhci->skel_term_qh);
+			goto check_qh_link;
+		}
+
+		head = &qh->node;
+		tmp = head->next;
+
+		while (tmp != head) {
+			qh = list_entry(tmp, struct uhci_qh, node);
+			tmp = tmp->next;
+			if (++cnt <= 10)
+				out += uhci_show_qh(uhci, qh, out,
+						len - (out - buf), 4);
+			if (!fsbr_link && qh->skel >= SKEL_FSBR)
+				fsbr_link = LINK_TO_QH(qh);
+		}
+		if ((cnt -= 10) > 0)
+			out += sprintf(out, "    Skipped %d QHs\n", cnt);
+
+		link = UHCI_PTR_TERM;
+		if (i <= SKEL_ISO)
+			;
+		else if (i < SKEL_ASYNC)
+			link = LINK_TO_QH(uhci->skel_async_qh);
+		else if (!uhci->fsbr_is_on)
+			;
+		else
+			link = LINK_TO_QH(uhci->skel_term_qh);
+check_qh_link:
+		if (qh->link != link)
+			out += sprintf(out, "    last QH not linked to next skeleton!\n");
+	}
+
+	return out - buf;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#define MAX_OUTPUT	(64 * 1024)
+
+struct uhci_debug {
+	int size;
+	char *data;
+};
+
+static int uhci_debug_open(struct inode *inode, struct file *file)
+{
+	struct uhci_hcd *uhci = inode->i_private;
+	struct uhci_debug *up;
+	int ret = -ENOMEM;
+	unsigned long flags;
+
+	lock_kernel();
+	up = kmalloc(sizeof(*up), GFP_KERNEL);
+	if (!up)
+		goto out;
+
+	up->data = kmalloc(MAX_OUTPUT, GFP_KERNEL);
+	if (!up->data) {
+		kfree(up);
+		goto out;
+	}
+
+	up->size = 0;
+	spin_lock_irqsave(&uhci->lock, flags);
+	if (uhci->is_initialized)
+		up->size = uhci_sprint_schedule(uhci, up->data, MAX_OUTPUT);
+	spin_unlock_irqrestore(&uhci->lock, flags);
+
+	file->private_data = up;
+
+	ret = 0;
+out:
+	unlock_kernel();
+	return ret;
+}
+
+static loff_t uhci_debug_lseek(struct file *file, loff_t off, int whence)
+{
+	struct uhci_debug *up;
+	loff_t new = -1;
+
+	lock_kernel();
+	up = file->private_data;
+
+	switch (whence) {
+	case 0:
+		new = off;
+		break;
+	case 1:
+		new = file->f_pos + off;
+		break;
+	}
+	if (new < 0 || new > up->size) {
+		unlock_kernel();
+		return -EINVAL;
+	}
+	unlock_kernel();
+	return (file->f_pos = new);
+}
+
+static ssize_t uhci_debug_read(struct file *file, char __user *buf,
+				size_t nbytes, loff_t *ppos)
+{
+	struct uhci_debug *up = file->private_data;
+	return simple_read_from_buffer(buf, nbytes, ppos, up->data, up->size);
+}
+
+static int uhci_debug_release(struct inode *inode, struct file *file)
+{
+	struct uhci_debug *up = file->private_data;
+
+	kfree(up->data);
+	kfree(up);
+
+	return 0;
+}
+
+#undef uhci_debug_operations
+static const struct file_operations uhci_debug_operations = {
+	.owner =	THIS_MODULE,
+	.open =		uhci_debug_open,
+	.llseek =	uhci_debug_lseek,
+	.read =		uhci_debug_read,
+	.release =	uhci_debug_release,
+};
+
+#endif	/* CONFIG_DEBUG_FS */
+
+#else	/* DEBUG */
+
+static inline void lprintk(char *buf)
+{}
+
+static inline int uhci_show_qh(struct uhci_hcd *uhci,
+		struct uhci_qh *qh, char *buf, int len, int space)
+{
+	return 0;
+}
+
+static inline int uhci_sprint_schedule(struct uhci_hcd *uhci,
+		char *buf, int len)
+{
+	return 0;
+}
+
+#endif
diff --git a/drivers/usb/astuhci/uhci-hcd.c b/drivers/usb/astuhci/uhci-hcd.c
new file mode 100644
index 0000000..fcfb6dbb
--- /dev/null
+++ b/drivers/usb/astuhci/uhci-hcd.c
@@ -0,0 +1,1229 @@
+/********************************************************************************
+* File Name     : uhci-hcd.c
+* 
+* port from uhci-hcd.c
+* 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/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/debugfs.h>
+#include <linux/pm.h>
+#include <linux/dmapool.h>
+#include <linux/dma-mapping.h>
+#include <linux/usb.h>
+#include <linux/bitops.h>
+#include <linux/dmi.h>
+#include <linux/platform_device.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include <mach/platform.h>
+#include "../core/hcd.h"
+#include "uhci-hcd.h"
+//#include "pci-quirks.h"
+
+/*
+ * Version Information
+ */
+#define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \
+Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \
+Alan Stern"
+#define DRIVER_DESC "USB Universal Host Controller Interface driver"
+
+/* for flakey hardware, ignore overcurrent indicators */
+static int ignore_oc;
+module_param(ignore_oc, bool, S_IRUGO);
+MODULE_PARM_DESC(ignore_oc, "ignore hardware overcurrent indications");
+
+/*
+ * debug = 0, no debugging messages
+ * debug = 1, dump failed URBs except for stalls
+ * debug = 2, dump all failed URBs (including stalls)
+ *            show all queues in /debug/uhci/[pci_addr]
+ * debug = 3, show all TDs in URBs when dumping
+ */
+#ifdef DEBUG
+#define DEBUG_CONFIGURED	1
+static int debug = 1;
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug level");
+
+#else
+#define DEBUG_CONFIGURED	0
+#define debug			0
+#endif
+
+
+
+static char *errbuf;
+#define ERRBUF_LEN    (32 * 1024)
+
+static struct kmem_cache *uhci_up_cachep;	/* urb_priv */
+
+void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state);
+void wakeup_rh(struct uhci_hcd *uhci);
+void uhci_get_current_frame_number(struct uhci_hcd *uhci);
+
+void uhci_reset_hc(struct uhci_hcd *uhci);
+int uhci_check_and_reset_hc(struct uhci_hcd *uhci);
+
+/*
+ * Calculate the link pointer DMA value for the first Skeleton QH in a frame.
+ */
+static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame)
+{
+	int skelnum;
+
+	/*
+	 * The interrupt queues will be interleaved as evenly as possible.
+	 * There's not much to be done about period-1 interrupts; they have
+	 * to occur in every frame.  But we can schedule period-2 interrupts
+	 * in odd-numbered frames, period-4 interrupts in frames congruent
+	 * to 2 (mod 4), and so on.  This way each frame only has two
+	 * interrupt QHs, which will help spread out bandwidth utilization.
+	 *
+	 * ffs (Find First bit Set) does exactly what we need:
+	 * 1,3,5,...  => ffs = 0 => use period-2 QH = skelqh[8],
+	 * 2,6,10,... => ffs = 1 => use period-4 QH = skelqh[7], etc.
+	 * ffs >= 7 => not on any high-period queue, so use
+	 *	period-1 QH = skelqh[9].
+	 * Add in UHCI_NUMFRAMES to insure at least one bit is set.
+	 */
+	skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES);
+	if (skelnum <= 1)
+		skelnum = 9;
+	return LINK_TO_QH(uhci->skelqh[skelnum]);
+}
+
+#include "uhci-debug.c"
+#include "uhci-q.c"
+#include "uhci-hub.c"
+
+/*
+ * Finish up a host controller reset and update the recorded state.
+ */
+void finish_reset(struct uhci_hcd *uhci)
+{
+	int port;
+
+	/* HCRESET doesn't affect the Suspend, Reset, and Resume Detect
+	 * bits in the port status and control registers.
+	 * We have to clear them by hand.
+	 */
+	for (port = 0; port < uhci->rh_numports; ++port)
+		writel(0, uhci->regbase + USBPORTSC1 + (port * 1));
+
+	uhci->port_c_suspend = uhci->resuming_ports = 0;
+	uhci->rh_state = UHCI_RH_RESET;
+	uhci->is_stopped = UHCI_IS_STOPPED;
+	uhci_to_hcd(uhci)->state = HC_STATE_HALT;
+	uhci_to_hcd(uhci)->poll_rh = 0;
+
+	uhci->dead = 0;		/* Full reset resurrects the controller */
+}
+
+/*
+ * Last rites for a defunct/nonfunctional controller
+ * or one we don't want to use any more.
+ */
+void uhci_hc_died(struct uhci_hcd *uhci)
+{
+	uhci_get_current_frame_number(uhci);
+//yriver
+//	uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr);
+	uhci_reset_hc(uhci);
+	finish_reset(uhci);
+	uhci->dead = 1;
+
+	/* The current frame may already be partway finished */
+	++uhci->frame_number;
+}
+
+/*
+ * Initialize a controller that was newly discovered or has lost power
+ * or otherwise been reset while it was suspended.  In none of these cases
+ * can we be sure of its previous state.
+ */
+void check_and_reset_hc(struct uhci_hcd *uhci)
+{
+//yriver
+//	if (uhci_check_and_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr))
+	if (uhci_check_and_reset_hc(uhci))
+		finish_reset(uhci);
+}
+
+/*
+ * Store the basic register settings needed by the controller.
+ */
+void configure_hc(struct uhci_hcd *uhci)
+{
+	/* Set the frame length to the default: 1 ms exactly */
+//	outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF);
+	writel(USBSOF_DEFAULT, uhci->regbase + USBSOF);
+
+	/* Store the frame list base address */
+//	outl(uhci->frame_dma_handle, uhci->io_addr + USBFLBASEADD);
+	writel(uhci->frame_dma_handle, uhci->regbase + USBFLBASEADD);
+
+	/* Set the current frame number */
+//	outw(uhci->frame_number & UHCI_MAX_SOF_NUMBER,
+//			uhci->io_addr + USBFRNUM);
+	writel(uhci->frame_number & UHCI_MAX_SOF_NUMBER,
+			uhci->regbase + USBFRNUM);
+
+	/* Mark controller as not halted before we enable interrupts */
+	uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED;
+	mb();
+	/* Enable PIRQ */
+//yriver
+//	pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
+//			USBLEGSUP_DEFAULT);
+}
+
+
+int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci)
+{
+/*
+
+	int port;
+
+
+	if (ignore_oc)
+		return 1;
+
+	switch (to_pci_dev(uhci_dev(uhci))->vendor) {
+	    default:
+		break;
+
+	    case PCI_VENDOR_ID_GENESYS:
+		return 1;
+
+	    case PCI_VENDOR_ID_INTEL:
+		for (port = 0; port < uhci->rh_numports; ++port) {
+			if (inw(uhci->io_addr + USBPORTSC1 + port * 2) &
+					USBPORTSC_OC)
+				return 1;
+		}
+		break;
+	}
+*/	
+	return 0;
+}
+
+int global_suspend_mode_is_broken(struct uhci_hcd *uhci)
+{
+	int port;
+	const char *sys_info;
+	static char bad_Asus_board[] = "A7V8X";
+
+	/* One of Asus's motherboards has a bug which causes it to
+	 * wake up immediately from suspend-to-RAM if any of the ports
+	 * are connected.  In such cases we will not set EGSM.
+	 */
+	sys_info = dmi_get_system_info(DMI_BOARD_NAME);
+	if (sys_info && !strcmp(sys_info, bad_Asus_board)) {
+		for (port = 0; port < uhci->rh_numports; ++port) {
+//yriver
+//			if (inw(uhci->io_addr + USBPORTSC1 + port * 2) &
+			if (readl(uhci->regbase + USBPORTSC1 + port * 1) &
+					USBPORTSC_CCS)
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state)
+__releases(uhci->lock)
+__acquires(uhci->lock)
+{
+	int auto_stop;
+	int int_enable, egsm_enable, wakeup_enable;
+	struct usb_device *rhdev = uhci_to_hcd(uhci)->self.root_hub;
+
+	auto_stop = (new_state == UHCI_RH_AUTO_STOPPED);
+	dev_dbg(&rhdev->dev, "%s%s\n", __func__,
+			(auto_stop ? " (auto-stop)" : ""));
+
+	/* Start off by assuming Resume-Detect interrupts and EGSM work
+	 * and that remote wakeups should be enabled.
+	 */
+	egsm_enable = USBCMD_EGSM;
+	uhci->RD_enable = 1;
+	int_enable = USBINTR_RESUME;
+	wakeup_enable = 1;
+/*
+	if (auto_stop) {
+		if (!device_may_wakeup(&rhdev->dev))
+			int_enable = 0;
+
+	} else {
+#ifdef CONFIG_PM
+		if (!rhdev->do_remote_wakeup)
+			wakeup_enable = 0;
+#endif
+	}
+
+	if (!wakeup_enable || global_suspend_mode_is_broken(uhci))
+		egsm_enable = 0;
+*/
+	/* If we're ignoring wakeup events then there's no reason to
+	 * enable Resume-Detect interrupts.  We also shouldn't enable
+	 * them if they are broken or disallowed.
+	 *
+	 * This logic may lead us to enabling RD but not EGSM.  The UHCI
+	 * spec foolishly says that RD works only when EGSM is on, but
+	 * there's no harm in enabling it anyway -- perhaps some chips
+	 * will implement it!
+	 */
+//yriver
+//	if (!wakeup_enable || resume_detect_interrupts_are_broken(uhci) ||
+//			!int_enable)
+//		uhci->RD_enable = int_enable = 0;
+
+//	outw(int_enable, uhci->io_addr + USBINTR);
+//	outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD);
+	writel(int_enable, uhci->regbase + USBINTR);
+//	writel(egsm_enable | USBCMD_CF, uhci->regbase + USBCMD);
+	writel(USBCMD_EGSM | USBCMD_CF, uhci->regbase + USBCMD);
+	mb();
+	udelay(5);
+
+	/* If we're auto-stopping then no devices have been attached
+	 * for a while, so there shouldn't be any active URBs and the
+	 * controller should stop after a few microseconds.  Otherwise
+	 * we will give the controller one frame to stop.
+	 */
+//yriver
+//	if (!auto_stop && !(inw(uhci->io_addr + USBSTS) & USBSTS_HCH)) {
+	if (!auto_stop && !(readl(uhci->regbase + USBSTS) & USBSTS_HCH)) {
+		uhci->rh_state = UHCI_RH_SUSPENDING;
+		spin_unlock_irq(&uhci->lock);
+		msleep(1);
+		spin_lock_irq(&uhci->lock);
+		if (uhci->dead)
+			return;
+	}
+//yriver
+//	if (!(inw(uhci->io_addr + USBSTS) & USBSTS_HCH))
+//	if (!(readl(uhci->regbase + USBSTS) & USBSTS_HCH))
+//		dev_warn(uhci_dev(uhci), "Controller not stopped yet!\n");
+
+	uhci_get_current_frame_number(uhci);
+
+	uhci->rh_state = new_state;
+	uhci->is_stopped = UHCI_IS_STOPPED;
+
+	/* If interrupts don't work and remote wakeup is enabled then
+	 * the suspended root hub needs to be polled.
+	 */
+//yriver
+//	uhci_to_hcd(uhci)->poll_rh = (!int_enable && wakeup_enable);
+	uhci_to_hcd(uhci)->poll_rh = !int_enable;
+
+	uhci_scan_schedule(uhci);
+	uhci_fsbr_off(uhci);
+}
+
+void start_rh(struct uhci_hcd *uhci)
+{
+	uhci_to_hcd(uhci)->state = HC_STATE_RUNNING;
+	uhci->is_stopped = 0;
+	/* Mark it configured and running with a 64-byte max packet.
+	 * All interrupts are enabled, even though RESUME won't do anything.
+	 */
+//yriver
+//	outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, uhci->io_addr + USBCMD);
+//	outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
+//			uhci->io_addr + USBINTR);
+
+	writel(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, uhci->regbase + USBCMD);
+	writel(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
+			uhci->regbase + USBINTR);
+	mb();
+	uhci->rh_state = UHCI_RH_RUNNING;
+	uhci_to_hcd(uhci)->poll_rh = 1;
+}
+
+void wakeup_rh(struct uhci_hcd *uhci)
+__releases(uhci->lock)
+__acquires(uhci->lock)
+{
+	dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev,
+			"%s%s\n", __func__,
+			uhci->rh_state == UHCI_RH_AUTO_STOPPED ?
+				" (auto-start)" : "");
+
+	/* If we are auto-stopped then no devices are attached so there's
+	 * no need for wakeup signals.  Otherwise we send Global Resume
+	 * for 20 ms.
+	 */
+	if (uhci->rh_state == UHCI_RH_SUSPENDED) {
+		uhci->rh_state = UHCI_RH_RESUMING;
+	}
+
+	start_rh(uhci);
+
+	/* Restart root hub polling */
+	mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
+}
+
+void wakeup_hc(struct uhci_hcd *uhci) {
+//	printk("wake_uhci\n");
+	wakeup_rh(uhci);
+	
+
+}
+
+irqreturn_t uhci_irq(struct usb_hcd *hcd)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	unsigned short status;
+
+	/*
+	 * Read the interrupt status, and write it back to clear the
+	 * interrupt cause.  Contrary to the UHCI specification, the
+	 * "HC Halted" status bit is persistent: it is RO, not R/WC.
+	 */
+//yriver
+//	status = inw(uhci->io_addr + USBSTS);
+	status = readl(uhci->regbase + USBSTS);
+	if (!(status & ~USBSTS_HCH))	/* shared interrupt, not mine */
+		return IRQ_NONE;
+//	outw(status, uhci->io_addr + USBSTS);		/* Clear it */
+	writel(status, uhci->regbase + USBSTS);		/* Clear it */
+
+	if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {
+		if (status & USBSTS_HSE)
+			dev_err(uhci_dev(uhci), "host system error, "
+					"PCI problems?\n");
+		if (status & USBSTS_HCPE)
+			dev_err(uhci_dev(uhci), "host controller process "
+					"error, something bad happened!\n");
+		if (status & USBSTS_HCH) {
+			spin_lock(&uhci->lock);
+			if (uhci->rh_state >= UHCI_RH_RUNNING) {
+				dev_err(uhci_dev(uhci),
+					"host controller halted, "
+					"very bad!\n");
+				if (debug > 1 && errbuf) {
+					/* Print the schedule for debugging */
+					uhci_sprint_schedule(uhci,
+							errbuf, ERRBUF_LEN);
+					lprintk(errbuf);
+				}
+				uhci_hc_died(uhci);
+
+				/* Force a callback in case there are
+				 * pending unlinks */
+//yriver
+//				mod_timer(&hcd->rh_timer, jiffies);
+				mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
+			}
+			spin_unlock(&uhci->lock);
+		}
+	}
+
+	if (status & USBSTS_RD)
+		usb_hcd_poll_rh_status(hcd);
+	else {
+		spin_lock(&uhci->lock);
+		uhci_scan_schedule(uhci);
+		spin_unlock(&uhci->lock);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Store the current frame number in uhci->frame_number if the controller
+ * is runnning.  Expand from 11 bits (of which we use only 10) to a
+ * full-sized integer.
+ *
+ * Like many other parts of the driver, this code relies on being polled
+ * more than once per second as long as the controller is running.
+ */
+void uhci_get_current_frame_number(struct uhci_hcd *uhci)
+{
+	if (!uhci->is_stopped) {
+		unsigned delta;
+//yriver
+//		delta = (inw(uhci->io_addr + USBFRNUM) - uhci->frame_number) &
+//				(UHCI_NUMFRAMES - 1);
+		delta = (readl(uhci->regbase + USBFRNUM) - uhci->frame_number) &
+				(UHCI_NUMFRAMES - 1);
+		uhci->frame_number += delta;
+	}
+}
+
+/*
+ * De-allocate all resources
+ */
+void release_uhci(struct uhci_hcd *uhci)
+{
+	int i;
+
+	if (DEBUG_CONFIGURED) {
+		spin_lock_irq(&uhci->lock);
+		uhci->is_initialized = 0;
+		spin_unlock_irq(&uhci->lock);
+
+		debugfs_remove(uhci->dentry);
+	}
+
+	for (i = 0; i < UHCI_NUM_SKELQH; i++)
+		uhci_free_qh(uhci, uhci->skelqh[i]);
+
+	uhci_free_td(uhci, uhci->term_td);
+
+	dma_pool_destroy(uhci->qh_pool);
+
+	dma_pool_destroy(uhci->td_pool);
+
+	kfree(uhci->frame_cpu);
+
+	dma_free_coherent(uhci_dev(uhci),
+			UHCI_NUMFRAMES * sizeof(*uhci->frame),
+			uhci->frame, uhci->frame_dma_handle);
+}
+
+void uhci_reset_hc(struct uhci_hcd *uhci)
+{
+	/* Reset the HC - this will force us to get a
+	 * new notification of any already connected
+	 * ports due to the virtual disconnect that it
+	 * implies.
+	 */
+    writel(0,(uhci->regbase + USBINTR));
+    writel(USBCMD_GRESET,(uhci->regbase + USBCMD));
+    mdelay(50);
+    
+    writel(0,(uhci->regbase + USBCMD));
+    mdelay(10);
+}
+
+int uhci_check_and_reset_hc(struct uhci_hcd *uhci)
+{ 
+    unsigned int cmd, intr;
+
+    cmd = readl((uhci->regbase + USBCMD));
+	if ((cmd & USBCMD_RS) || !(cmd & USBCMD_CF) ||
+			!(cmd & USBCMD_EGSM)) {
+		printk("%s: cmd = 0x%04x\n", __FUNCTION__, cmd);
+		goto reset_needed;
+	}
+
+	//intr = inw(base + UHCI_USBINTR);
+    intr = readl((uhci->regbase + USBINTR));
+	if (intr & (~USBINTR_RESUME)) {
+		printk("%s: intr = 0x%04x\n", __FUNCTION__, intr);
+		goto reset_needed;
+	}
+	return 0;
+
+reset_needed:
+//	printk("Performing full reset\n");
+	uhci_reset_hc(uhci);
+	return 1;
+}
+
+int uhci_reset(struct usb_hcd *hcd)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+
+	
+#ifdef CONFIG_GUC_USB_UHCI_MULTIPORT_2
+	uhci->rh_numports = 2;
+#elif defined (CONFIG_GUC_USB_UHCI_MULTIPORT_4)
+	uhci->rh_numports = 4;
+#else
+	uhci->rh_numports = 1;
+#endif
+
+	/* Kick BIOS off this hardware and reset if the controller
+	 * isn't already safely quiescent.
+	 */
+	check_and_reset_hc(uhci);
+	return 0;
+}
+
+int uhci_init(struct usb_hcd *hcd)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	//unsigned io_size = (unsigned) hcd->rsrc_len;
+	int port;
+
+	uhci->io_addr = (unsigned long) hcd->rsrc_start;
+
+	/* The UHCI spec says devices must have 2 ports, and goes on to say
+	 * they may have more but gives no way to determine how many there
+	 * are.  However according to the UHCI spec, Bit 7 of the port
+	 * status and control register is always set to 1.  So we try to
+	 * use this to our advantage.  Another common failure mode when
+	 * a nonexistent register is addressed is to return all ones, so
+	 * we test for that also.
+	 */
+	for (port = 0; port < UHCI_RH_MAXCHILD; port++) {
+		unsigned int portstatus;
+//yriver
+//		portstatus = inw(uhci->io_addr + USBPORTSC1 + (port * 2));
+		portstatus = readl(uhci->regbase + USBPORTSC1 + (port * 1));
+		if (!(portstatus & 0x0080) || portstatus == 0xffff)
+			break;
+	}
+	if (debug) {
+		dev_info(uhci_dev(uhci), "detected %d ports\n", port);
+	}
+
+	/* Anything greater than 7 is weird so we'll ignore it. */
+	if (port > UHCI_RH_MAXCHILD) {
+		dev_info(uhci_dev(uhci), "port count misdetected? "
+				"forcing to 2 ports\n");
+		port = 2;
+	}
+	uhci->rh_numports = port;
+
+	/* Kick BIOS off this hardware and reset if the controller
+	 * isn't already safely quiescent.
+	 */
+	check_and_reset_hc(uhci);
+	return 0;
+}
+
+/* Make sure the controller is quiescent and that we're not using it
+ * any more.  This is mainly for the benefit of programs which, like kexec,
+ * expect the hardware to be idle: not doing DMA or generating IRQs.
+ *
+ * This routine may be called in a damaged or failing kernel.  Hence we
+ * do not acquire the spinlock before shutting down the controller.
+ */
+void uhci_shutdown(struct pci_dev *pdev)
+{
+	struct usb_hcd *hcd = (struct usb_hcd *) pci_get_drvdata(pdev);
+
+	uhci_hc_died(hcd_to_uhci(hcd));
+}
+
+/*
+ * Allocate a frame list, and then setup the skeleton
+ *
+ * The hardware doesn't really know any difference
+ * in the queues, but the order does matter for the
+ * protocols higher up.  The order in which the queues
+ * are encountered by the hardware is:
+ *
+ *  - All isochronous events are handled before any
+ *    of the queues. We don't do that here, because
+ *    we'll create the actual TD entries on demand.
+ *  - The first queue is the high-period interrupt queue.
+ *  - The second queue is the period-1 interrupt and async
+ *    (low-speed control, full-speed control, then bulk) queue.
+ *  - The third queue is the terminating bandwidth reclamation queue,
+ *    which contains no members, loops back to itself, and is present
+ *    only when FSBR is on and there are no full-speed control or bulk QHs.
+ */
+int uhci_start(struct usb_hcd *hcd)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	int retval = -EBUSY;
+	int i;
+	struct dentry *dentry;
+
+	hcd->uses_new_polling = 1;
+
+	spin_lock_init(&uhci->lock);
+	setup_timer(&uhci->fsbr_timer, uhci_fsbr_timeout,
+			(unsigned long) uhci);
+	INIT_LIST_HEAD(&uhci->idle_qh_list);
+	init_waitqueue_head(&uhci->waitqh);
+
+	if (DEBUG_CONFIGURED) {
+		dentry = debugfs_create_file(hcd->self.bus_name,
+				S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root,
+				uhci, &uhci_debug_operations);
+		if (!dentry) {
+			dev_err(uhci_dev(uhci), "couldn't create uhci "
+					"debugfs entry\n");
+			retval = -ENOMEM;
+			goto err_create_debug_entry;
+		}
+		uhci->dentry = dentry;
+	}
+
+	uhci->frame = dma_alloc_coherent(uhci_dev(uhci),
+			UHCI_NUMFRAMES * sizeof(*uhci->frame),
+			&uhci->frame_dma_handle, 0);
+	if (!uhci->frame) {
+		dev_err(uhci_dev(uhci), "unable to allocate "
+				"consistent memory for frame list\n");
+		goto err_alloc_frame;
+	}
+
+	memset(uhci->frame, 0, UHCI_NUMFRAMES * sizeof(*uhci->frame));
+
+	uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu),
+			GFP_KERNEL);
+	if (!uhci->frame_cpu) {
+		dev_err(uhci_dev(uhci), "unable to allocate "
+				"memory for frame pointers\n");
+		goto err_alloc_frame_cpu;
+	}
+
+	uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci),
+			sizeof(struct uhci_td), 16, 0);
+	if (!uhci->td_pool) {
+		dev_err(uhci_dev(uhci), "unable to create td dma_pool\n");
+		goto err_create_td_pool;
+	}
+
+	uhci->qh_pool = dma_pool_create("uhci_qh", uhci_dev(uhci),
+			sizeof(struct uhci_qh), 16, 0);
+	if (!uhci->qh_pool) {
+		dev_err(uhci_dev(uhci), "unable to create qh dma_pool\n");
+		goto err_create_qh_pool;
+	}
+
+	uhci->term_td = uhci_alloc_td(uhci);
+	if (!uhci->term_td) {
+		dev_err(uhci_dev(uhci), "unable to allocate terminating TD\n");
+		goto err_alloc_term_td;
+	}
+
+	for (i = 0; i < UHCI_NUM_SKELQH; i++) {
+		uhci->skelqh[i] = uhci_alloc_qh(uhci, NULL, NULL);
+		if (!uhci->skelqh[i]) {
+			dev_err(uhci_dev(uhci), "unable to allocate QH\n");
+			goto err_alloc_skelqh;
+		}
+	}
+
+	/*
+	 * 8 Interrupt queues; link all higher int queues to int1 = async
+	 */
+	for (i = SKEL_ISO + 1; i < SKEL_ASYNC; ++i)
+		uhci->skelqh[i]->link = LINK_TO_QH(uhci->skel_async_qh);
+	uhci->skel_async_qh->link = UHCI_PTR_TERM;
+	uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_term_qh);
+
+	/* This dummy TD is to work around a bug in Intel PIIX controllers */
+	uhci_fill_td(uhci->term_td, 0, uhci_explen(0) |
+			(0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0);
+	uhci->term_td->link = UHCI_PTR_TERM;
+	uhci->skel_async_qh->element = uhci->skel_term_qh->element =
+			LINK_TO_TD(uhci->term_td);
+
+	/*
+	 * Fill the frame list: make all entries point to the proper
+	 * interrupt queue.
+	 */
+	for (i = 0; i < UHCI_NUMFRAMES; i++) {
+
+		/* Only place we don't use the frame list routines */
+		uhci->frame[i] = uhci_frame_skel_link(uhci, i);
+	}
+
+	/*
+	 * Some architectures require a full mb() to enforce completion of
+	 * the memory writes above before the I/O transfers in configure_hc().
+	 */
+	mb();
+
+	configure_hc(uhci);
+
+	uhci->is_initialized = 1;
+	start_rh(uhci);
+
+	return 0;
+
+/*
+ * error exits:
+ */
+err_alloc_skelqh:
+	for (i = 0; i < UHCI_NUM_SKELQH; i++) {
+		if (uhci->skelqh[i])
+			uhci_free_qh(uhci, uhci->skelqh[i]);
+	}
+
+	uhci_free_td(uhci, uhci->term_td);
+
+err_alloc_term_td:
+	dma_pool_destroy(uhci->qh_pool);
+
+err_create_qh_pool:
+	dma_pool_destroy(uhci->td_pool);
+
+err_create_td_pool:
+	kfree(uhci->frame_cpu);
+
+err_alloc_frame_cpu:
+	dma_free_coherent(uhci_dev(uhci),
+			UHCI_NUMFRAMES * sizeof(*uhci->frame),
+			uhci->frame, uhci->frame_dma_handle);
+
+err_alloc_frame:
+	debugfs_remove(uhci->dentry);
+
+err_create_debug_entry:
+	return retval;
+}
+
+void uhci_stop(struct usb_hcd *hcd)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+
+	spin_lock_irq(&uhci->lock);
+	if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) && !uhci->dead)
+		uhci_hc_died(uhci);
+	uhci_scan_schedule(uhci);
+	spin_unlock_irq(&uhci->lock);
+
+	del_timer_sync(&uhci->fsbr_timer);
+	release_uhci(uhci);
+}
+
+void stop_hc(struct uhci_hcd *uhci)
+{
+    // Disable all interrupts
+    writel(0, (uhci->regbase + USBINTR));
+    writel(USBCMD_MAXP,(uhci->regbase + USBCMD)); // disable hc
+                
+}
+
+#ifdef CONFIG_PM
+int uhci_rh_suspend(struct usb_hcd *hcd)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	int rc = 0;
+
+	spin_lock_irq(&uhci->lock);
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
+		rc = -ESHUTDOWN;
+	else if (!uhci->dead)
+		suspend_rh(uhci, UHCI_RH_SUSPENDED);
+	spin_unlock_irq(&uhci->lock);
+	return rc;
+}
+
+int uhci_rh_resume(struct usb_hcd *hcd)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	int rc = 0;
+
+	spin_lock_irq(&uhci->lock);
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
+		rc = -ESHUTDOWN;
+	else if (!uhci->dead)
+		wakeup_rh(uhci);
+	spin_unlock_irq(&uhci->lock);
+	return rc;
+}
+
+int uhci_pci_suspend(struct usb_hcd *hcd, pm_message_t message)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	int rc = 0;
+
+	dev_dbg(uhci_dev(uhci), "%s\n", __func__);
+
+	spin_lock_irq(&uhci->lock);
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead)
+		goto done_okay;		/* Already suspended or dead */
+
+	if (uhci->rh_state > UHCI_RH_SUSPENDED) {
+		dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n");
+		rc = -EBUSY;
+		goto done;
+	};
+
+	/* All PCI host controllers are required to disable IRQ generation
+	 * at the source, so we must turn off PIRQ.
+	 */
+	pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
+	mb();
+	hcd->poll_rh = 0;
+
+	/* FIXME: Enable non-PME# remote wakeup? */
+
+	/* make sure snapshot being resumed re-enumerates everything */
+	if (message.event == PM_EVENT_PRETHAW)
+		uhci_hc_died(uhci);
+
+done_okay:
+	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+done:
+	spin_unlock_irq(&uhci->lock);
+	return rc;
+}
+
+int uhci_pci_resume(struct usb_hcd *hcd)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+
+	dev_dbg(uhci_dev(uhci), "%s\n", __func__);
+
+	/* Since we aren't in D3 any more, it's safe to set this flag
+	 * even if the controller was dead.
+	 */
+	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+	mb();
+
+	spin_lock_irq(&uhci->lock);
+
+	/* FIXME: Disable non-PME# remote wakeup? */
+
+	/* The firmware or a boot kernel may have changed the controller
+	 * settings during a system wakeup.  Check it and reconfigure
+	 * to avoid problems.
+	 */
+	check_and_reset_hc(uhci);
+
+	/* If the controller was dead before, it's back alive now */
+	configure_hc(uhci);
+
+	if (uhci->rh_state == UHCI_RH_RESET) {
+
+		/* The controller had to be reset */
+		usb_root_hub_lost_power(hcd->self.root_hub);
+		suspend_rh(uhci, UHCI_RH_SUSPENDED);
+	}
+
+	spin_unlock_irq(&uhci->lock);
+
+	/* If interrupts don't work and remote wakeup is enabled then
+	 * the suspended root hub needs to be polled.
+	 */
+	if (!uhci->RD_enable && hcd->self.root_hub->do_remote_wakeup) {
+		hcd->poll_rh = 1;
+		usb_hcd_poll_rh_status(hcd);
+	}
+	return 0;
+}
+#endif
+
+/* Wait until a particular device/endpoint's QH is idle, and free it */
+void uhci_hcd_endpoint_disable(struct usb_hcd *hcd,
+		struct usb_host_endpoint *hep)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	struct uhci_qh *qh;
+
+	spin_lock_irq(&uhci->lock);
+	qh = (struct uhci_qh *) hep->hcpriv;
+	if (qh == NULL)
+		goto done;
+
+	while (qh->state != UHCI_QH_STATE_IDLE) {
+		++uhci->num_waiting;
+		spin_unlock_irq(&uhci->lock);
+		wait_event_interruptible(uhci->waitqh,
+				qh->state == UHCI_QH_STATE_IDLE);
+		spin_lock_irq(&uhci->lock);
+		--uhci->num_waiting;
+	}
+
+	uhci_free_qh(uhci, qh);
+done:
+	spin_unlock_irq(&uhci->lock);
+}
+
+int uhci_hcd_get_frame_number(struct usb_hcd *hcd)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	unsigned frame_number;
+	unsigned delta;
+
+	/* Minimize latency by avoiding the spinlock */
+	frame_number = uhci->frame_number;
+	barrier();
+//yriver
+//	delta = (inw(uhci->io_addr + USBFRNUM) - frame_number) &
+//			(UHCI_NUMFRAMES - 1);
+	delta = (readl(uhci->regbase	 + USBFRNUM) - frame_number) &
+			(UHCI_NUMFRAMES - 1);
+	return frame_number + delta;
+}
+
+//static const char hcd_name[] = "uhci_hcd";
+
+static const struct hc_driver _uhci_driver = {
+//yriver
+//	.description =		hcd_name,
+	.description =		"ast uhci",
+	.product_desc =		"UHCI Host Controller",
+	.hcd_priv_size =	sizeof(struct uhci_hcd),
+
+	/* Generic hardware linkage */
+	.irq =			uhci_irq,
+	.flags =		HCD_USB11,
+
+	/* Basic lifecycle operations */
+//	.reset =		uhci_init,
+	.reset =		uhci_reset,
+	.start =		uhci_start,
+#ifdef CONFIG_PM
+	.pci_suspend =		uhci_pci_suspend,
+	.pci_resume =		uhci_pci_resume,
+	.bus_suspend =		uhci_rh_suspend,
+	.bus_resume =		uhci_rh_resume,
+#endif
+	.stop =			uhci_stop,
+
+	.urb_enqueue =		uhci_urb_enqueue,
+	.urb_dequeue =		uhci_urb_dequeue,
+
+	.endpoint_disable =	uhci_hcd_endpoint_disable,
+	.get_frame_number =	uhci_hcd_get_frame_number,
+
+	.hub_status_data =	uhci_hub_status_data,
+	.hub_control =		uhci_hub_control,
+};
+
+int __init uhci_hcd_init(void)
+{
+	int retval = -ENOMEM;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	printk(KERN_INFO "uhci_hcd: " DRIVER_DESC "%s\n",
+			ignore_oc ? ", overcurrent ignored" : "");
+	set_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
+
+	if (DEBUG_CONFIGURED) {
+		errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL);
+		if (!errbuf)
+			goto errbuf_failed;
+		uhci_debugfs_root = debugfs_create_dir("uhci", NULL);
+		if (!uhci_debugfs_root)
+			goto debug_failed;
+	}
+
+	uhci_up_cachep = kmem_cache_create("uhci_urb_priv",
+		sizeof(struct urb_priv), 0, 0, NULL);
+	if (!uhci_up_cachep)
+		goto up_failed;
+/*
+	retval = pci_register_driver(&uhci_pci_driver);
+	if (retval)
+		goto init_failed;
+*/
+	return 0;
+
+//init_failed:
+//	kmem_cache_destroy(uhci_up_cachep);
+
+up_failed:
+	debugfs_remove(uhci_debugfs_root);
+
+debug_failed:
+	kfree(errbuf);
+
+errbuf_failed:
+
+	clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
+	return retval;
+}
+
+void uhci_hcd_cleanup(void) 
+{
+//	pci_unregister_driver(&uhci_pci_driver);
+	kmem_cache_destroy(uhci_up_cachep);
+	debugfs_remove(uhci_debugfs_root);
+	kfree(errbuf);
+	clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
+}
+
+void __exit cleanup_UHCI(void)
+{
+    uhci_hcd_cleanup();
+}
+
+/*-------------------------------------------------------------------------*/
+static int usb_hcd_guc_probe (const struct hc_driver *driver,
+			  struct platform_device *pdev)
+{
+	unsigned int *base, temp;
+	int retval;
+	struct resource *res;	
+	struct usb_hcd *hcd = 0;
+	struct uhci_hcd *uhci;
+	int irq;
+	
+	irq = platform_get_irq(pdev, 0);
+	if (irq <= 0) {
+		dev_err(&pdev->dev,
+			"Found HC with no IRQ. Check %s setup!\n",
+			dev_name(&pdev->dev));
+		retval = -ENODEV;
+		goto err1;
+	}
+
+	hcd = usb_create_hcd (driver, &pdev->dev, dev_name(&pdev->dev));	
+//	printk("alloc_uhci(2): uhci_dev:%x, _uhci_hcd.state:%x\n", &uhci_dev, _uhci_hcd->state);
+	if (!hcd) {
+		retval = -ENOMEM;
+		return retval;
+	}
+
+
+	uhci = hcd_to_uhci(hcd);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev,
+			"Found HC with no register addr. Check %s setup!\n",
+			dev_name(&pdev->dev));
+		retval = -ENODEV;
+		goto err1;
+	}
+
+	if (!request_mem_region(res->start, res->end - res->start + 1,
+				res->name)) {
+		dev_dbg(&pdev->dev, "controller already in use\n");
+		retval = -EBUSY;
+		goto err1;
+	}
+
+	base = ioremap_nocache(res->start, res->end - res->start + 1);
+	if (base == NULL) {
+		dev_dbg(&pdev->dev, "error mapping memory\n");
+		retval = -ENOMEM;
+		goto err1;
+	}
+
+	uhci->regbase = (unsigned int *)base;
+	uhci->io_addr = (unsigned int)base;
+
+//	printk("UHCI Base address is %x, phy %08x\n",(unsigned int)base, UHC_BASE_ADDR);
+
+	retval = usb_add_hcd (hcd, irq, IRQF_SHARED);
+	
+	//    printk("alloc_uhci(3): uhci_dev:%x, _uhci_hcd.state:%x\n", &uhci_dev, _uhci_hcd->state);
+
+	if (retval == 0)
+		return retval;
+
+	//BruceToDo. Stop USB 1.1 Host's clock.
+	iounmap((void*)uhci->io_addr);
+err1:
+	usb_put_hcd(hcd);
+
+	printk("add UHCI to USB host controller list failed!\n");
+	return retval;
+}
+
+
+static inline void
+usb_hcd_guc_remove (struct usb_hcd *hcd, struct platform_device *pdev)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+
+	usb_remove_hcd(hcd);
+	//BruceToDo. Stop USB 1.1 Host's clock.
+	iounmap((void*)uhci->io_addr);
+	usb_put_hcd(hcd);
+}
+
+/*-------------------------------------------------------------------------*/
+#ifdef	CONFIG_PM
+static int uhci_guc_suspend(struct platform_device *dev, pm_message_t message)
+{
+	struct uhci_hcd	*uhci = hcd_to_uhci(platform_get_drvdata(dev));
+#if 0
+	if (time_before(jiffies, ohci->next_statechange))
+		msleep(5);
+	ohci->next_statechange = jiffies;
+	omap_ohci_clock_power(0);
+#endif
+	uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED;
+	return 0;
+}
+static int uhci_guc_resume(struct platform_device *dev)
+{
+	struct usb_hcd	*hcd = platform_get_drvdata(dev);
+#if 0
+	struct uhci_hcd	*uhci = hcd_to_uhci(hcd);
+
+	if (time_before(jiffies, ohci->next_statechange))
+		msleep(5);
+	ohci->next_statechange = jiffies;
+	omap_ohci_clock_power(1);
+	ohci_finish_controller_resume(hcd);
+#endif
+
+	/*Bruce111220. This line is copied from AST1510 uhci-hcd.c and OMAP kernel 2.6.15*/
+	usb_hcd_resume_root_hub(hcd);
+	return 0;
+}
+#endif
+/*-------------------------------------------------------------------------*/
+
+static int uhci_hcd_guc_drv_probe(struct platform_device *dev)
+{
+	return usb_hcd_guc_probe(&_uhci_driver, dev);
+}
+static int uhci_hcd_guc_drv_remove(struct platform_device *dev)
+{
+	struct usb_hcd		*hcd = platform_get_drvdata(dev);
+
+	usb_hcd_guc_remove(hcd, dev);
+	platform_set_drvdata(dev, NULL);
+	return 0;
+}
+
+/*
+ * Driver definition to register
+ */
+static struct platform_driver uhci_hcd_guc_driver = {
+	.probe		= uhci_hcd_guc_drv_probe,
+	.remove		= uhci_hcd_guc_drv_remove,
+#ifdef	CONFIG_PM
+	.suspend	= uhci_guc_suspend,
+	.resume		= uhci_guc_resume,
+#endif
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "ast_uhci",
+	},
+};
+
+static int __init uhci_hcd_guc_init (void)
+{
+	uhci_hcd_init();
+	return platform_driver_register(&uhci_hcd_guc_driver);
+}
+
+static void __exit uhci_hcd_guc_cleanup (void)
+{
+	uhci_hcd_cleanup();
+	platform_driver_unregister(&uhci_hcd_guc_driver);
+}
+
+module_init(uhci_hcd_guc_init);
+module_exit(uhci_hcd_guc_cleanup);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/astuhci/uhci-hcd.h b/drivers/usb/astuhci/uhci-hcd.h
new file mode 100644
index 0000000..c4a903e
--- /dev/null
+++ b/drivers/usb/astuhci/uhci-hcd.h
@@ -0,0 +1,496 @@
+/********************************************************************************
+* File Name     : uhci-hcd.h
+* 
+* port from uhci-hcd.h
+* 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 __LINUX_UHCI_HCD_H
+#define __LINUX_UHCI_HCD_H
+
+#include <linux/list.h>
+#include <linux/usb.h>
+
+#define usb_packetid(pipe)	(usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT)
+#define PIPE_DEVEP_MASK		0x0007ff00
+
+
+/*
+ * Universal Host Controller Interface data structures and defines
+ */
+
+/* Command register */
+#define USBCMD		0
+#define   USBCMD_RS		0x0001	/* Run/Stop */
+#define   USBCMD_HCRESET	0x0002	/* Host reset */
+#define   USBCMD_GRESET		0x0004	/* Global reset */
+#define   USBCMD_EGSM		0x0008	/* Global Suspend Mode */
+#define   USBCMD_FGR		0x0010	/* Force Global Resume */
+#define   USBCMD_SWDBG		0x0020	/* SW Debug mode */
+#define   USBCMD_CF		0x0040	/* Config Flag (sw only) */
+#define   USBCMD_MAXP		0x0080	/* Max Packet (0 = 32, 1 = 64) */
+
+/* Status register */
+//#define USBSTS		2
+#define USBSTS		1
+#define   USBSTS_USBINT		0x0001	/* Interrupt due to IOC */
+#define   USBSTS_ERROR		0x0002	/* Interrupt due to error */
+#define   USBSTS_RD		0x0004	/* Resume Detect */
+#define   USBSTS_HSE		0x0008	/* Host System Error: PCI problems */
+#define   USBSTS_HCPE		0x0010	/* Host Controller Process Error:
+					 * the schedule is buggy */
+#define   USBSTS_HCH		0x0020	/* HC Halted */
+
+/* Interrupt enable register */
+//#define USBINTR		4
+#define USBINTR		2
+#define   USBINTR_TIMEOUT	0x0001	/* Timeout/CRC error enable */
+#define   USBINTR_RESUME	0x0002	/* Resume interrupt enable */
+#define   USBINTR_IOC		0x0004	/* Interrupt On Complete enable */
+#define   USBINTR_SP		0x0008	/* Short packet interrupt enable */
+
+//#define USBFRNUM	6
+//#define USBFLBASEADD	8
+//#define USBSOF		12
+#define USBFRNUM	32
+#define USBFLBASEADD	3
+#define USBSOF		33
+#define   USBSOF_DEFAULT	64	/* Frame length is exactly 1 ms */
+
+/* USB port status and control registers */
+//#define USBPORTSC1	16
+//#define USBPORTSC2	18
+#define USBPORTSC1	(34)
+#define USBPORTSC2	(35)
+#define   USBPORTSC_CCS		0x0001	/* Current Connect Status
+					 * ("device present") */
+#define   USBPORTSC_CSC		0x0002	/* Connect Status Change */
+#define   USBPORTSC_PE		0x0004	/* Port Enable */
+#define   USBPORTSC_PEC		0x0008	/* Port Enable Change */
+#define   USBPORTSC_DPLUS	0x0010	/* D+ high (line status) */
+#define   USBPORTSC_DMINUS	0x0020	/* D- high (line status) */
+#define   USBPORTSC_RD		0x0040	/* Resume Detect */
+#define   USBPORTSC_RES1	0x0080	/* reserved, always 1 */
+#define   USBPORTSC_LSDA	0x0100	/* Low Speed Device Attached */
+#define   USBPORTSC_PR		0x0200	/* Port Reset */
+/* OC and OCC from Intel 430TX and later (not UHCI 1.1d spec) */
+#define   USBPORTSC_OC		0x0400	/* Over Current condition */
+#define   USBPORTSC_OCC		0x0800	/* Over Current Change R/WC */
+#define   USBPORTSC_SUSP	0x1000	/* Suspend */
+#define   USBPORTSC_RES2	0x2000	/* reserved, write zeroes */
+#define   USBPORTSC_RES3	0x4000	/* reserved, write zeroes */
+#define   USBPORTSC_RES4	0x8000	/* reserved, write zeroes */
+
+/* Legacy support register */
+#define USBLEGSUP		0xc0
+#define   USBLEGSUP_DEFAULT	0x2000	/* only PIRQ enable set */
+#define   USBLEGSUP_RWC		0x8f00	/* the R/WC bits */
+#define   USBLEGSUP_RO		0x5040	/* R/O and reserved bits */
+
+#define UHCI_PTR_BITS		__constant_cpu_to_le32(0x000F)
+#define UHCI_PTR_TERM		__constant_cpu_to_le32(0x0001)
+#define UHCI_PTR_QH		__constant_cpu_to_le32(0x0002)
+#define UHCI_PTR_DEPTH		__constant_cpu_to_le32(0x0004)
+#define UHCI_PTR_BREADTH	__constant_cpu_to_le32(0x0000)
+
+#define UHCI_NUMFRAMES		1024	/* in the frame list [array] */
+#define UHCI_MAX_SOF_NUMBER	2047	/* in an SOF packet */
+#define CAN_SCHEDULE_FRAMES	1000	/* how far in the future frames
+					 * can be scheduled */
+#define MAX_PHASE		32	/* Periodic scheduling length */
+
+/* Otg Features*/
+#define RH_PORT_BHNP_ENABLE  0x03
+#define RH_PORT_AHNP_SUPPORT 0x04
+#define SF_BHNP_ENABLE 0x34
+
+/* When no queues need Full-Speed Bandwidth Reclamation,
+ * delay this long before turning FSBR off */
+#define FSBR_OFF_DELAY		msecs_to_jiffies(10)
+
+/* If a queue hasn't advanced after this much time, assume it is stuck */
+#define QH_WAIT_TIMEOUT		msecs_to_jiffies(200)
+
+
+/*
+ *	Queue Headers
+ */
+
+/*
+ * One role of a QH is to hold a queue of TDs for some endpoint.  One QH goes
+ * with each endpoint, and qh->element (updated by the HC) is either:
+ *   - the next unprocessed TD in the endpoint's queue, or
+ *   - UHCI_PTR_TERM (when there's no more traffic for this endpoint).
+ *
+ * The other role of a QH is to serve as a "skeleton" framelist entry, so we
+ * can easily splice a QH for some endpoint into the schedule at the right
+ * place.  Then qh->element is UHCI_PTR_TERM.
+ *
+ * In the schedule, qh->link maintains a list of QHs seen by the HC:
+ *     skel1 --> ep1-qh --> ep2-qh --> ... --> skel2 --> ...
+ *
+ * qh->node is the software equivalent of qh->link.  The differences
+ * are that the software list is doubly-linked and QHs in the UNLINKING
+ * state are on the software list but not the hardware schedule.
+ *
+ * For bookkeeping purposes we maintain QHs even for Isochronous endpoints,
+ * but they never get added to the hardware schedule.
+ */
+#define QH_STATE_IDLE		1	/* QH is not being used */
+#define UHCI_QH_STATE_IDLE	1	/* QH is not being used */
+#define QH_STATE_UNLINKING	2	/* QH has been removed from the
+					 * schedule but the hardware may
+					 * still be using it */
+#define QH_STATE_ACTIVE		3	/* QH is on the schedule */
+
+struct uhci_qh {
+	/* Hardware fields */
+	__le32 link;			/* Next QH in the schedule */
+	__le32 element;			/* Queue element (TD) pointer */
+
+	/* Software fields */
+	dma_addr_t dma_handle;
+
+	struct list_head node;		/* Node in the list of QHs */
+	struct usb_host_endpoint *hep;	/* Endpoint information */
+	struct usb_device *udev;
+	struct list_head queue;		/* Queue of urbps for this QH */
+	struct uhci_td *dummy_td;	/* Dummy TD to end the queue */
+	struct uhci_td *post_td;	/* Last TD completed */
+
+	struct usb_iso_packet_descriptor *iso_packet_desc;
+					/* Next urb->iso_frame_desc entry */
+	unsigned long advance_jiffies;	/* Time of last queue advance */
+	unsigned int unlink_frame;	/* When the QH was unlinked */
+	unsigned int period;		/* For Interrupt and Isochronous QHs */
+	short phase;			/* Between 0 and period-1 */
+	short load;			/* Periodic time requirement, in us */
+	unsigned int iso_frame;		/* Frame # for iso_packet_desc */
+
+	int state;			/* QH_STATE_xxx; see above */
+	int type;			/* Queue type (control, bulk, etc) */
+	int skel;			/* Skeleton queue number */
+
+	unsigned int initial_toggle:1;	/* Endpoint's current toggle value */
+	unsigned int needs_fixup:1;	/* Must fix the TD toggle values */
+	unsigned int is_stopped:1;	/* Queue was stopped by error/unlink */
+	unsigned int wait_expired:1;	/* QH_WAIT_TIMEOUT has expired */
+	unsigned int bandwidth_reserved:1;	/* Periodic bandwidth has
+						 * been allocated */
+} __attribute__((aligned(16)));
+
+/*
+ * We need a special accessor for the element pointer because it is
+ * subject to asynchronous updates by the controller.
+ */
+static inline __le32 qh_element(struct uhci_qh *qh) {
+	__le32 element = qh->element;
+
+	barrier();
+	return element;
+}
+
+#define LINK_TO_QH(qh)		(UHCI_PTR_QH | cpu_to_le32((qh)->dma_handle))
+
+
+/*
+ *	Transfer Descriptors
+ */
+
+/*
+ * for TD <status>:
+ */
+#define TD_CTRL_SPD		(1 << 29)	/* Short Packet Detect */
+#define TD_CTRL_C_ERR_MASK	(3 << 27)	/* Error Counter bits */
+#define TD_CTRL_C_ERR_SHIFT	27
+#define TD_CTRL_LS		(1 << 26)	/* Low Speed Device */
+#define TD_CTRL_IOS		(1 << 25)	/* Isochronous Select */
+#define TD_CTRL_IOC		(1 << 24)	/* Interrupt on Complete */
+#define TD_CTRL_ACTIVE		(1 << 23)	/* TD Active */
+#define TD_CTRL_STALLED		(1 << 22)	/* TD Stalled */
+#define TD_CTRL_DBUFERR		(1 << 21)	/* Data Buffer Error */
+#define TD_CTRL_BABBLE		(1 << 20)	/* Babble Detected */
+#define TD_CTRL_NAK		(1 << 19)	/* NAK Received */
+#define TD_CTRL_CRCTIMEO	(1 << 18)	/* CRC/Time Out Error */
+#define TD_CTRL_BITSTUFF	(1 << 17)	/* Bit Stuff Error */
+#define TD_CTRL_ACTLEN_MASK	0x7FF	/* actual length, encoded as n - 1 */
+
+#define TD_CTRL_ANY_ERROR	(TD_CTRL_STALLED | TD_CTRL_DBUFERR | \
+				 TD_CTRL_BABBLE | TD_CTRL_CRCTIME | \
+				 TD_CTRL_BITSTUFF)
+
+#define uhci_maxerr(err)		((err) << TD_CTRL_C_ERR_SHIFT)
+#define uhci_status_bits(ctrl_sts)	((ctrl_sts) & 0xF60000)
+#define uhci_actual_length(ctrl_sts)	(((ctrl_sts) + 1) & \
+			TD_CTRL_ACTLEN_MASK)	/* 1-based */
+
+/*
+ * for TD <info>: (a.k.a. Token)
+ */
+#define td_token(td)		le32_to_cpu((td)->token)
+#define TD_TOKEN_DEVADDR_SHIFT	8
+#define TD_TOKEN_TOGGLE_SHIFT	19
+#define TD_TOKEN_TOGGLE		(1 << 19)
+#define TD_TOKEN_EXPLEN_SHIFT	21
+#define TD_TOKEN_EXPLEN_MASK	0x7FF	/* expected length, encoded as n-1 */
+#define TD_TOKEN_PID_MASK	0xFF
+
+#define uhci_explen(len)	((((len) - 1) & TD_TOKEN_EXPLEN_MASK) << \
+					TD_TOKEN_EXPLEN_SHIFT)
+
+#define uhci_expected_length(token) ((((token) >> TD_TOKEN_EXPLEN_SHIFT) + \
+					1) & TD_TOKEN_EXPLEN_MASK)
+#define uhci_toggle(token)	(((token) >> TD_TOKEN_TOGGLE_SHIFT) & 1)
+#define uhci_endpoint(token)	(((token) >> 15) & 0xf)
+#define uhci_devaddr(token)	(((token) >> TD_TOKEN_DEVADDR_SHIFT) & 0x7f)
+#define uhci_devep(token)	(((token) >> TD_TOKEN_DEVADDR_SHIFT) & 0x7ff)
+#define uhci_packetid(token)	((token) & TD_TOKEN_PID_MASK)
+#define uhci_packetout(token)	(uhci_packetid(token) != USB_PID_IN)
+#define uhci_packetin(token)	(uhci_packetid(token) == USB_PID_IN)
+
+/*
+ * The documentation says "4 words for hardware, 4 words for software".
+ *
+ * That's silly, the hardware doesn't care. The hardware only cares that
+ * the hardware words are 16-byte aligned, and we can have any amount of
+ * sw space after the TD entry.
+ *
+ * td->link points to either another TD (not necessarily for the same urb or
+ * even the same endpoint), or nothing (PTR_TERM), or a QH.
+ */
+struct uhci_td {
+	/* Hardware fields */
+	__le32 link;
+	__le32 status;
+	__le32 token;
+	__le32 buffer;
+
+	/* Software fields */
+	dma_addr_t dma_handle;
+
+	struct list_head list;
+
+	int frame;			/* for iso: what frame? */
+	struct list_head fl_list;
+} __attribute__((aligned(16)));
+
+/*
+ * We need a special accessor for the control/status word because it is
+ * subject to asynchronous updates by the controller.
+ */
+static inline u32 td_status(struct uhci_td *td) {
+	__le32 status = td->status;
+
+	barrier();
+	return le32_to_cpu(status);
+}
+
+#define LINK_TO_TD(td)		(cpu_to_le32((td)->dma_handle))
+
+
+/*
+ *	Skeleton Queue Headers
+ */
+
+/*
+ * The UHCI driver uses QHs with Interrupt, Control and Bulk URBs for
+ * automatic queuing. To make it easy to insert entries into the schedule,
+ * we have a skeleton of QHs for each predefined Interrupt latency.
+ * Asynchronous QHs (low-speed control, full-speed control, and bulk)
+ * go onto the period-1 interrupt list, since they all get accessed on
+ * every frame.
+ *
+ * When we want to add a new QH, we add it to the list starting from the
+ * appropriate skeleton QH.  For instance, the schedule can look like this:
+ *
+ * skel int128 QH
+ * dev 1 interrupt QH
+ * dev 5 interrupt QH
+ * skel int64 QH
+ * skel int32 QH
+ * ...
+ * skel int1 + async QH
+ * dev 5 low-speed control QH
+ * dev 1 bulk QH
+ * dev 2 bulk QH
+ *
+ * There is a special terminating QH used to keep full-speed bandwidth
+ * reclamation active when no full-speed control or bulk QHs are linked
+ * into the schedule.  It has an inactive TD (to work around a PIIX bug,
+ * see the Intel errata) and it points back to itself.
+ *
+ * There's a special skeleton QH for Isochronous QHs which never appears
+ * on the schedule.  Isochronous TDs go on the schedule before the
+ * the skeleton QHs.  The hardware accesses them directly rather than
+ * through their QH, which is used only for bookkeeping purposes.
+ * While the UHCI spec doesn't forbid the use of QHs for Isochronous,
+ * it doesn't use them either.  And the spec says that queues never
+ * advance on an error completion status, which makes them totally
+ * unsuitable for Isochronous transfers.
+ *
+ * There's also a special skeleton QH used for QHs which are in the process
+ * of unlinking and so may still be in use by the hardware.  It too never
+ * appears on the schedule.
+ */
+
+#define UHCI_NUM_SKELQH		11
+#define SKEL_UNLINK		0
+#define skel_unlink_qh		skelqh[SKEL_UNLINK]
+#define SKEL_ISO		1
+#define skel_iso_qh		skelqh[SKEL_ISO]
+	/* int128, int64, ..., int1 = 2, 3, ..., 9 */
+#define SKEL_INDEX(exponent)	(9 - exponent)
+#define SKEL_ASYNC		9
+#define skel_async_qh		skelqh[SKEL_ASYNC]
+#define SKEL_TERM		10
+#define skel_term_qh		skelqh[SKEL_TERM]
+
+/* The following entries refer to sublists of skel_async_qh */
+#define SKEL_LS_CONTROL		20
+#define SKEL_FS_CONTROL		21
+#define SKEL_FSBR		SKEL_FS_CONTROL
+#define SKEL_BULK		22
+
+/*
+ *	The UHCI controller and root hub
+ */
+
+/*
+ * States for the root hub:
+ *
+ * To prevent "bouncing" in the presence of electrical noise,
+ * when there are no devices attached we delay for 1 second in the
+ * RUNNING_NODEVS state before switching to the AUTO_STOPPED state.
+ * 
+ * (Note that the AUTO_STOPPED state won't be necessary once the hub
+ * driver learns to autosuspend.)
+ */
+enum uhci_rh_state {
+	/* In the following states the HC must be halted.
+	 * These two must come first. */
+	UHCI_RH_RESET,
+	UHCI_RH_SUSPENDED,
+
+	UHCI_RH_AUTO_STOPPED,
+	UHCI_RH_RESUMING,
+
+	/* In this state the HC changes from running to halted,
+	 * so it can legally appear either way. */
+	UHCI_RH_SUSPENDING,
+
+	/* In the following states it's an error if the HC is halted.
+	 * These two must come last. */
+	UHCI_RH_RUNNING,		/* The normal state */
+	UHCI_RH_RUNNING_NODEVS,		/* Running with no devices attached */
+};
+
+/*
+ * The full UHCI controller information:
+ */
+struct uhci_hcd {
+
+	/* debugfs */
+	struct dentry *dentry;
+
+	/* Grabbed from PCI */
+	unsigned long io_addr;
+
+	struct dma_pool *qh_pool;
+	struct dma_pool *td_pool;
+
+	struct uhci_td *term_td;	/* Terminating TD, see UHCI bug */
+	struct uhci_qh *skelqh[UHCI_NUM_SKELQH];	/* Skeleton QHs */
+	struct uhci_qh *next_qh;	/* Next QH to scan */
+
+	spinlock_t lock;
+
+	dma_addr_t frame_dma_handle;	/* Hardware frame list */
+	__le32 *frame;
+	void **frame_cpu;		/* CPU's frame list */
+
+	enum uhci_rh_state rh_state;
+	unsigned long auto_stop_time;		/* When to AUTO_STOP */
+
+	unsigned int frame_number;		/* As of last check */
+	unsigned int is_stopped;
+#define UHCI_IS_STOPPED		9999		/* Larger than a frame # */
+	unsigned int last_iso_frame;		/* Frame of last scan */
+	unsigned int cur_iso_frame;		/* Frame for current scan */
+
+	unsigned int scan_in_progress:1;	/* Schedule scan is running */
+	unsigned int need_rescan:1;		/* Redo the schedule scan */
+	unsigned int dead:1;			/* Controller has died */
+	unsigned int RD_enable:1;		/* Suspended root hub with
+						   Resume-Detect interrupts
+						   enabled */
+	unsigned int is_initialized:1;		/* Data structure is usable */
+	unsigned int fsbr_is_on:1;		/* FSBR is turned on */
+	unsigned int fsbr_is_wanted:1;		/* Does any URB want FSBR? */
+	unsigned int fsbr_expiring:1;		/* FSBR is timing out */
+
+	struct timer_list fsbr_timer;		/* For turning off FBSR */
+
+	/* Support for port suspend/resume/reset */
+	unsigned long port_c_suspend;		/* Bit-arrays of ports */
+	unsigned long resuming_ports;
+	unsigned long ports_timeout;		/* Time to stop signalling */
+
+	struct list_head idle_qh_list;		/* Where the idle QHs live */
+
+	int rh_numports;			/* Number of root-hub ports */
+
+	wait_queue_head_t waitqh;		/* endpoint_disable waiters */
+	int num_waiting;			/* Number of waiters */
+
+	int total_load;				/* Sum of array values */
+	short load[MAX_PHASE];			/* Periodic allocations */
+	int is_suspended;
+	unsigned int *regbase;  // eric
+	unsigned int *ptr_usb_hcd; // eric
+};
+
+/* Convert between a usb_hcd pointer and the corresponding uhci_hcd */
+static inline struct uhci_hcd *hcd_to_uhci(struct usb_hcd *hcd)
+{
+	return (struct uhci_hcd *) (hcd->hcd_priv);
+}
+static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci)
+{
+	return container_of((void *) uhci, struct usb_hcd, hcd_priv);
+}
+
+#define uhci_dev(u)	(uhci_to_hcd(u)->self.controller)
+
+/* Utility macro for comparing frame numbers */
+#define uhci_frame_before_eq(f1, f2)	(0 <= (int) ((f2) - (f1)))
+
+
+/*
+ *	Private per-URB data
+ */
+struct urb_priv {
+	struct list_head node;		/* Node in the QH's urbp list */
+
+	struct urb *urb;
+
+	struct uhci_qh *qh;		/* QH for this URB */
+	struct list_head td_list;
+
+	unsigned fsbr:1;		/* URB wants FSBR */
+};
+
+
+/* Some special IDs */
+
+#define PCI_VENDOR_ID_GENESYS		0x17a0
+#define PCI_DEVICE_ID_GL880S_UHCI	0x8083
+
+#endif
diff --git a/drivers/usb/astuhci/uhci-hub.c b/drivers/usb/astuhci/uhci-hub.c
new file mode 100644
index 0000000..64a4496
--- /dev/null
+++ b/drivers/usb/astuhci/uhci-hub.c
@@ -0,0 +1,437 @@
+/********************************************************************************
+* File Name     : uhci-hub.c
+* 
+* port from uhci-hub.c
+* 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 
+********************************************************************************/
+
+static const __u8 root_hub_hub_des[] =
+{
+	0x09,			/*  __u8  bLength; */
+	0x29,			/*  __u8  bDescriptorType; Hub-descriptor */
+	0x02,			/*  __u8  bNbrPorts; */
+	0x0a,			/* __u16  wHubCharacteristics; */
+	0x00,			/*   (per-port OC, no power switching) */
+	0x01,			/*  __u8  bPwrOn2pwrGood; 2ms */
+	0x00,			/*  __u8  bHubContrCurrent; 0 mA */
+	0x00,			/*  __u8  DeviceRemovable; *** 7 Ports max *** */
+	0xff			/*  __u8  PortPwrCtrlMask; *** 7 ports max *** */
+};
+
+#define	UHCI_RH_MAXCHILD	7
+
+/* must write as zeroes */
+#define WZ_BITS		(USBPORTSC_RES2 | USBPORTSC_RES3 | USBPORTSC_RES4)
+
+/* status change bits:  nonzero writes will clear */
+#define RWC_BITS	(USBPORTSC_OCC | USBPORTSC_PEC | USBPORTSC_CSC)
+
+/* suspend/resume bits: port suspended or port resuming */
+#define SUSPEND_BITS	(USBPORTSC_SUSP | USBPORTSC_RD)
+
+/* A port that either is connected or has a changed-bit set will prevent
+ * us from AUTO_STOPPING.
+ */
+static int any_ports_active(struct uhci_hcd *uhci)
+{
+	int port;
+
+	for (port = 0; port < uhci->rh_numports; ++port) {
+//yriver
+//		if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) &
+		if ((readl(uhci->regbase + USBPORTSC1 + port * 1) &
+				(USBPORTSC_CCS | RWC_BITS)) ||
+				test_bit(port, &uhci->port_c_suspend))
+			return 1;
+	}
+	return 0;
+}
+
+static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf)
+{
+	int port;
+	int mask = RWC_BITS;
+
+	/* Some boards (both VIA and Intel apparently) report bogus
+	 * overcurrent indications, causing massive log spam unless
+	 * we completely ignore them.  This doesn't seem to be a problem
+	 * with the chipset so much as with the way it is connected on
+	 * the motherboard; if the overcurrent input is left to float
+	 * then it may constantly register false positives. */
+	if (ignore_oc)
+		mask &= ~USBPORTSC_OCC;
+
+	*buf = 0;
+	for (port = 0; port < uhci->rh_numports; ++port) {
+//yriver
+//		if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & mask) ||
+		if ((readl(uhci->regbase + USBPORTSC1 + port * 1) & mask) ||
+				test_bit(port, &uhci->port_c_suspend))
+			*buf |= (1 << (port + 1));
+	}
+	return !!*buf;
+}
+
+#define OK(x)			len = (x); break
+//yriver
+#define CLR_RH_PORTSTAT(x) \
+	status = readl(port_addr); \
+	status &= ~(RWC_BITS|WZ_BITS); \
+	status &= ~(x); \
+	status |= RWC_BITS & (x); \
+	writel(status, port_addr)
+
+#define SET_RH_PORTSTAT(x) \
+	status = readl(port_addr); \
+	status |= (x); \
+	status &= ~(RWC_BITS|WZ_BITS); \
+	writel(status, port_addr)
+
+/* UHCI controllers don't automatically stop resume signalling after 20 msec,
+ * so we have to poll and check timeouts in order to take care of it.
+ */
+static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,
+		unsigned long port_addr)
+{
+	int status;
+	int i;
+//yriver
+//	if (inw(port_addr) & SUSPEND_BITS) {
+	if (readl(port_addr) & SUSPEND_BITS) {
+		CLR_RH_PORTSTAT(SUSPEND_BITS);
+		if (test_bit(port, &uhci->resuming_ports))
+			set_bit(port, &uhci->port_c_suspend);
+
+		/* The controller won't actually turn off the RD bit until
+		 * it has had a chance to send a low-speed EOP sequence,
+		 * which is supposed to take 3 bit times (= 2 microseconds).
+		 * Experiments show that some controllers take longer, so
+		 * we'll poll for completion. */
+		for (i = 0; i < 10; ++i) {
+//yriver
+//			if (!(inw(port_addr) & SUSPEND_BITS))
+			if (!(readl(port_addr) & SUSPEND_BITS))
+				break;
+			udelay(1);
+		}
+	}
+	clear_bit(port, &uhci->resuming_ports);
+}
+
+/* Wait for the UHCI controller in HP's iLO2 server management chip.
+ * It can take up to 250 us to finish a reset and set the CSC bit.
+ */
+static void wait_for_HP(unsigned long port_addr)
+{
+	int i;
+
+	for (i = 10; i < 250; i += 10) {
+//yriver
+//		if (inw(port_addr) & USBPORTSC_CSC)
+		if (readl(port_addr) & USBPORTSC_CSC)
+			return;
+		udelay(10);
+	}
+	/* Log a warning? */
+}
+
+static void uhci_check_ports(struct uhci_hcd *uhci)
+{
+	unsigned int port;
+	unsigned long port_addr;
+	int status;
+
+	for (port = 0; port < uhci->rh_numports; ++port) {
+//yriver
+//		port_addr = uhci->io_addr + USBPORTSC1 + 2 * port;
+//		status = inw(port_addr);
+		port_addr = uhci->regbase + USBPORTSC1 + 1 * port;
+		status = readl(port_addr);
+		if (unlikely(status & USBPORTSC_PR)) {
+			if (time_after_eq(jiffies, uhci->ports_timeout)) {
+				CLR_RH_PORTSTAT(USBPORTSC_PR);
+				udelay(10);
+
+				/* HP's server management chip requires
+				 * a longer delay. */
+				if (to_pci_dev(uhci_dev(uhci))->vendor ==
+						PCI_VENDOR_ID_HP)
+					wait_for_HP(port_addr);
+
+				/* If the port was enabled before, turning
+				 * reset on caused a port enable change.
+				 * Turning reset off causes a port connect
+				 * status change.  Clear these changes. */
+				CLR_RH_PORTSTAT(USBPORTSC_CSC | USBPORTSC_PEC);
+				SET_RH_PORTSTAT(USBPORTSC_PE);
+			}
+		}
+		if (unlikely(status & USBPORTSC_RD)) {
+			if (!test_bit(port, &uhci->resuming_ports)) {
+
+				/* Port received a wakeup request */
+				set_bit(port, &uhci->resuming_ports);
+				uhci->ports_timeout = jiffies +
+						msecs_to_jiffies(20);
+
+				/* Make sure we see the port again
+				 * after the resuming period is over. */
+				mod_timer(&uhci_to_hcd(uhci)->rh_timer,
+						uhci->ports_timeout);
+			} else if (time_after_eq(jiffies,
+						uhci->ports_timeout)) {
+				uhci_finish_suspend(uhci, port, port_addr);
+			}
+		}
+	}
+}
+
+static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	unsigned long flags;
+	int status = 0;
+
+	spin_lock_irqsave(&uhci->lock, flags);
+
+	uhci_scan_schedule(uhci);
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead)
+		goto done;
+	uhci_check_ports(uhci);
+
+	status = get_hub_status_data(uhci, buf);
+
+	switch (uhci->rh_state) {
+	    case UHCI_RH_SUSPENDING:
+	    case UHCI_RH_SUSPENDED:
+		/* if port change, ask to be resumed */
+		if (status)
+			usb_hcd_resume_root_hub(hcd);
+		break;
+
+	    case UHCI_RH_AUTO_STOPPED:
+		/* if port change, auto start */
+		if (status)
+			wakeup_rh(uhci);
+		break;
+
+	    case UHCI_RH_RUNNING:
+		/* are any devices attached? */
+		if (!any_ports_active(uhci)) {
+			uhci->rh_state = UHCI_RH_RUNNING_NODEVS;
+			uhci->auto_stop_time = jiffies + HZ;
+		}
+		break;
+
+	    case UHCI_RH_RUNNING_NODEVS:
+		/* auto-stop if nothing connected for 1 second */
+		if (any_ports_active(uhci))
+			uhci->rh_state = UHCI_RH_RUNNING;
+//yriver
+//		else if (time_after_eq(jiffies, uhci->auto_stop_time))
+//			suspend_rh(uhci, UHCI_RH_AUTO_STOPPED);
+		break;
+
+	    default:
+		break;
+	}
+
+done:
+	spin_unlock_irqrestore(&uhci->lock, flags);
+	return status;
+}
+
+/* size of returned buffer is part of USB spec */
+static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+			u16 wIndex, char *buf, u16 wLength)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	int status, lstatus, retval = 0, len = 0;
+//yriver
+//	unsigned int port = wIndex - 1;
+//	unsigned long port_addr = uhci->io_addr + USBPORTSC1 + 2 * port;
+	unsigned int port = wIndex - 1;
+	unsigned long port_addr = uhci->regbase + USBPORTSC1 + 1 * port;
+	u16 wPortChange, wPortStatus;
+	unsigned long flags;
+
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead)
+		return -ETIMEDOUT;
+
+	spin_lock_irqsave(&uhci->lock, flags);
+	switch (typeReq) {
+
+	case GetHubStatus:
+		*(__le32 *)buf = cpu_to_le32(0);
+		OK(4);		/* hub power */
+	case GetPortStatus:
+		if (port >= uhci->rh_numports)
+			goto err;
+
+		uhci_check_ports(uhci);
+//yriver
+//		status = inw(port_addr);
+		status = readl(port_addr);
+
+		/* Intel controllers report the OverCurrent bit active on.
+		 * VIA controllers report it active off, so we'll adjust the
+		 * bit value.  (It's not standardized in the UHCI spec.)
+		 */
+		if (to_pci_dev(hcd->self.controller)->vendor ==
+				PCI_VENDOR_ID_VIA)
+			status ^= USBPORTSC_OC;
+
+		/* UHCI doesn't support C_RESET (always false) */
+		wPortChange = lstatus = 0;
+		if (status & USBPORTSC_CSC)
+			wPortChange |= USB_PORT_STAT_C_CONNECTION;
+		if (status & USBPORTSC_PEC)
+			wPortChange |= USB_PORT_STAT_C_ENABLE;
+		if ((status & USBPORTSC_OCC) && !ignore_oc)
+			wPortChange |= USB_PORT_STAT_C_OVERCURRENT;
+
+		if (test_bit(port, &uhci->port_c_suspend)) {
+			wPortChange |= USB_PORT_STAT_C_SUSPEND;
+			lstatus |= 1;
+		}
+		if (test_bit(port, &uhci->resuming_ports))
+			lstatus |= 4;
+
+		/* UHCI has no power switching (always on) */
+		wPortStatus = USB_PORT_STAT_POWER;
+		if (status & USBPORTSC_CCS)
+			wPortStatus |= USB_PORT_STAT_CONNECTION;
+		if (status & USBPORTSC_PE) {
+			wPortStatus |= USB_PORT_STAT_ENABLE;
+			if (status & SUSPEND_BITS)
+				wPortStatus |= USB_PORT_STAT_SUSPEND;
+		}
+		if (status & USBPORTSC_OC)
+			wPortStatus |= USB_PORT_STAT_OVERCURRENT;
+		if (status & USBPORTSC_PR)
+			wPortStatus |= USB_PORT_STAT_RESET;
+		if (status & USBPORTSC_LSDA)
+			wPortStatus |= USB_PORT_STAT_LOW_SPEED;
+
+		if (wPortChange)
+			dev_dbg(uhci_dev(uhci), "port %d portsc %04x,%02x\n",
+					wIndex, status, lstatus);
+
+		*(__le16 *)buf = cpu_to_le16(wPortStatus);
+		*(__le16 *)(buf + 2) = cpu_to_le16(wPortChange);
+		OK(4);
+	case SetHubFeature:		/* We don't implement these */
+	case ClearHubFeature:
+		switch (wValue) {
+		case C_HUB_OVER_CURRENT:
+		case C_HUB_LOCAL_POWER:
+			OK(0);
+		default:
+			goto err;
+		}
+		break;
+	case SetPortFeature:
+		if (port >= uhci->rh_numports)
+			goto err;
+
+		switch (wValue) {
+		case USB_PORT_FEAT_SUSPEND:
+			SET_RH_PORTSTAT(USBPORTSC_SUSP);
+			OK(0);
+		case USB_PORT_FEAT_RESET:
+			SET_RH_PORTSTAT(USBPORTSC_PR);
+
+			/* Reset terminates Resume signalling */
+			uhci_finish_suspend(uhci, port, port_addr);
+
+			/* USB v2.0 7.1.7.5 */
+			uhci->ports_timeout = jiffies + msecs_to_jiffies(50);
+			OK(0);
+		case USB_PORT_FEAT_POWER:
+			/* UHCI has no power switching */
+			OK(0);
+		default:
+			goto err;
+		}
+		break;
+	case ClearPortFeature:
+		if (port >= uhci->rh_numports)
+			goto err;
+
+		switch (wValue) {
+		case USB_PORT_FEAT_ENABLE:
+			CLR_RH_PORTSTAT(USBPORTSC_PE);
+
+			/* Disable terminates Resume signalling */
+			uhci_finish_suspend(uhci, port, port_addr);
+			OK(0);
+		case USB_PORT_FEAT_C_ENABLE:
+			CLR_RH_PORTSTAT(USBPORTSC_PEC);
+			OK(0);
+		case USB_PORT_FEAT_SUSPEND:
+//yriver
+//			if (!(inw(port_addr) & USBPORTSC_SUSP)) {
+			if (!(readl(port_addr) & USBPORTSC_SUSP)) {
+
+				/* Make certain the port isn't suspended */
+				uhci_finish_suspend(uhci, port, port_addr);
+			} else if (!test_and_set_bit(port,
+						&uhci->resuming_ports)) {
+				SET_RH_PORTSTAT(USBPORTSC_RD);
+
+				/* The controller won't allow RD to be set
+				 * if the port is disabled.  When this happens
+				 * just skip the Resume signalling.
+				 */
+//yriver
+//				if (!(inw(port_addr) & USBPORTSC_RD))
+				if (!(readl(port_addr) & USBPORTSC_RD))
+					uhci_finish_suspend(uhci, port,
+							port_addr);
+				else
+					/* USB v2.0 7.1.7.7 */
+					uhci->ports_timeout = jiffies +
+						msecs_to_jiffies(20);
+			}
+			OK(0);
+		case USB_PORT_FEAT_C_SUSPEND:
+			clear_bit(port, &uhci->port_c_suspend);
+			OK(0);
+		case USB_PORT_FEAT_POWER:
+			/* UHCI has no power switching */
+			goto err;
+		case USB_PORT_FEAT_C_CONNECTION:
+			CLR_RH_PORTSTAT(USBPORTSC_CSC);
+			OK(0);
+		case USB_PORT_FEAT_C_OVER_CURRENT:
+			CLR_RH_PORTSTAT(USBPORTSC_OCC);
+			OK(0);
+		case USB_PORT_FEAT_C_RESET:
+			/* this driver won't report these */
+			OK(0);
+		default:
+			goto err;
+		}
+		break;
+	case GetHubDescriptor:
+		len = min_t(unsigned int, sizeof(root_hub_hub_des), wLength);
+		memcpy(buf, root_hub_hub_des, len);
+		if (len > 2)
+			buf[2] = uhci->rh_numports;
+		OK(len);
+	default:
+err:
+		retval = -EPIPE;
+	}
+	spin_unlock_irqrestore(&uhci->lock, flags);
+
+	return retval;
+}
diff --git a/drivers/usb/astuhci/uhci-q.c b/drivers/usb/astuhci/uhci-q.c
new file mode 100644
index 0000000..eb24599
--- /dev/null
+++ b/drivers/usb/astuhci/uhci-q.c
@@ -0,0 +1,1760 @@
+/********************************************************************************
+* File Name     : uhci-q.c
+* 
+* port from uhci-q.c
+* 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 
+********************************************************************************/
+static void uhci_set_next_interrupt(struct uhci_hcd *uhci)
+{
+	if (uhci->is_stopped)
+		mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
+	uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC); 
+}
+
+static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci)
+{
+	uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC);
+}
+
+
+/*
+ * Full-Speed Bandwidth Reclamation (FSBR).
+ * We turn on FSBR whenever a queue that wants it is advancing,
+ * and leave it on for a short time thereafter.
+ */
+static void uhci_fsbr_on(struct uhci_hcd *uhci)
+{
+	struct uhci_qh *lqh;
+
+	/* The terminating skeleton QH always points back to the first
+	 * FSBR QH.  Make the last async QH point to the terminating
+	 * skeleton QH. */
+	uhci->fsbr_is_on = 1;
+	lqh = list_entry(uhci->skel_async_qh->node.prev,
+			struct uhci_qh, node);
+	lqh->link = LINK_TO_QH(uhci->skel_term_qh);
+}
+
+static void uhci_fsbr_off(struct uhci_hcd *uhci)
+{
+	struct uhci_qh *lqh;
+
+	/* Remove the link from the last async QH to the terminating
+	 * skeleton QH. */
+	uhci->fsbr_is_on = 0;
+	lqh = list_entry(uhci->skel_async_qh->node.prev,
+			struct uhci_qh, node);
+	lqh->link = UHCI_PTR_TERM;
+}
+
+static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb)
+{
+	struct urb_priv *urbp = urb->hcpriv;
+
+	if (!(urb->transfer_flags & URB_NO_FSBR))
+		urbp->fsbr = 1;
+}
+
+static void uhci_urbp_wants_fsbr(struct uhci_hcd *uhci, struct urb_priv *urbp)
+{
+	if (urbp->fsbr) {
+		uhci->fsbr_is_wanted = 1;
+		if (!uhci->fsbr_is_on)
+			uhci_fsbr_on(uhci);
+		else if (uhci->fsbr_expiring) {
+			uhci->fsbr_expiring = 0;
+			del_timer(&uhci->fsbr_timer);
+		}
+	}
+}
+
+static void uhci_fsbr_timeout(unsigned long _uhci)
+{
+	struct uhci_hcd *uhci = (struct uhci_hcd *) _uhci;
+	unsigned long flags;
+
+	spin_lock_irqsave(&uhci->lock, flags);
+	if (uhci->fsbr_expiring) {
+		uhci->fsbr_expiring = 0;
+		uhci_fsbr_off(uhci);
+	}
+	spin_unlock_irqrestore(&uhci->lock, flags);
+}
+
+
+static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
+{
+	dma_addr_t dma_handle;
+	struct uhci_td *td;
+
+	td = dma_pool_alloc(uhci->td_pool, GFP_ATOMIC, &dma_handle);
+	if (!td)
+		return NULL;
+
+	td->dma_handle = dma_handle;
+	td->frame = -1;
+
+	INIT_LIST_HEAD(&td->list);
+	INIT_LIST_HEAD(&td->fl_list);
+
+	return td;
+}
+
+static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
+{
+	if (!list_empty(&td->list))
+		dev_WARN(uhci_dev(uhci), "td %p still in list!\n", td);
+	if (!list_empty(&td->fl_list))
+		dev_WARN(uhci_dev(uhci), "td %p still in fl_list!\n", td);
+
+	dma_pool_free(uhci->td_pool, td, td->dma_handle);
+}
+
+static inline void uhci_fill_td(struct uhci_td *td, u32 status,
+		u32 token, u32 buffer)
+{
+	td->status = cpu_to_le32(status);
+	td->token = cpu_to_le32(token);
+	td->buffer = cpu_to_le32(buffer);
+}
+
+static void uhci_add_td_to_urbp(struct uhci_td *td, struct urb_priv *urbp)
+{
+	list_add_tail(&td->list, &urbp->td_list);
+}
+
+static void uhci_remove_td_from_urbp(struct uhci_td *td)
+{
+	list_del_init(&td->list);
+}
+
+/*
+ * We insert Isochronous URBs directly into the frame list at the beginning
+ */
+static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci,
+		struct uhci_td *td, unsigned framenum)
+{
+	framenum &= (UHCI_NUMFRAMES - 1);
+
+	td->frame = framenum;
+
+	/* Is there a TD already mapped there? */
+	if (uhci->frame_cpu[framenum]) {
+		struct uhci_td *ftd, *ltd;
+
+		ftd = uhci->frame_cpu[framenum];
+		ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list);
+
+		list_add_tail(&td->fl_list, &ftd->fl_list);
+
+		td->link = ltd->link;
+		wmb();
+		ltd->link = LINK_TO_TD(td);
+	} else {
+		td->link = uhci->frame[framenum];
+		wmb();
+		uhci->frame[framenum] = LINK_TO_TD(td);
+		uhci->frame_cpu[framenum] = td;
+	}
+}
+
+static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci,
+		struct uhci_td *td)
+{
+	/* If it's not inserted, don't remove it */
+	if (td->frame == -1) {
+		WARN_ON(!list_empty(&td->fl_list));
+		return;
+	}
+
+	if (uhci->frame_cpu[td->frame] == td) {
+		if (list_empty(&td->fl_list)) {
+			uhci->frame[td->frame] = td->link;
+			uhci->frame_cpu[td->frame] = NULL;
+		} else {
+			struct uhci_td *ntd;
+
+			ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list);
+			uhci->frame[td->frame] = LINK_TO_TD(ntd);
+			uhci->frame_cpu[td->frame] = ntd;
+		}
+	} else {
+		struct uhci_td *ptd;
+
+		ptd = list_entry(td->fl_list.prev, struct uhci_td, fl_list);
+		ptd->link = td->link;
+	}
+
+	list_del_init(&td->fl_list);
+	td->frame = -1;
+}
+
+static inline void uhci_remove_tds_from_frame(struct uhci_hcd *uhci,
+		unsigned int framenum)
+{
+	struct uhci_td *ftd, *ltd;
+
+	framenum &= (UHCI_NUMFRAMES - 1);
+
+	ftd = uhci->frame_cpu[framenum];
+	if (ftd) {
+		ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list);
+		uhci->frame[framenum] = ltd->link;
+		uhci->frame_cpu[framenum] = NULL;
+
+		while (!list_empty(&ftd->fl_list))
+			list_del_init(ftd->fl_list.prev);
+	}
+}
+
+/*
+ * Remove all the TDs for an Isochronous URB from the frame list
+ */
+static void uhci_unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb)
+{
+	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
+	struct uhci_td *td;
+
+	list_for_each_entry(td, &urbp->td_list, list)
+		uhci_remove_td_from_frame_list(uhci, td);
+}
+
+static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
+		struct usb_device *udev, struct usb_host_endpoint *hep)
+{
+	dma_addr_t dma_handle;
+	struct uhci_qh *qh;
+
+	qh = dma_pool_alloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle);
+	if (!qh)
+		return NULL;
+
+	memset(qh, 0, sizeof(*qh));
+	qh->dma_handle = dma_handle;
+
+	qh->element = UHCI_PTR_TERM;
+	qh->link = UHCI_PTR_TERM;
+
+	INIT_LIST_HEAD(&qh->queue);
+	INIT_LIST_HEAD(&qh->node);
+
+	if (udev) {		/* Normal QH */
+		qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+		if (qh->type != USB_ENDPOINT_XFER_ISOC) {
+			qh->dummy_td = uhci_alloc_td(uhci);
+			if (!qh->dummy_td) {
+				dma_pool_free(uhci->qh_pool, qh, dma_handle);
+				return NULL;
+			}
+		}
+//yriver
+//		qh->state = QH_STATE_IDLE;
+		qh->state = UHCI_QH_STATE_IDLE;
+		qh->hep = hep;
+		qh->udev = udev;
+		hep->hcpriv = qh;
+
+		if (qh->type == USB_ENDPOINT_XFER_INT ||
+				qh->type == USB_ENDPOINT_XFER_ISOC)
+			qh->load = usb_calc_bus_time(udev->speed,
+					usb_endpoint_dir_in(&hep->desc),
+					qh->type == USB_ENDPOINT_XFER_ISOC,
+					le16_to_cpu(hep->desc.wMaxPacketSize))
+				/ 1000 + 1;
+
+	} else {		/* Skeleton QH */
+		qh->state = QH_STATE_ACTIVE;
+		qh->type = -1;
+	}
+	return qh;
+}
+
+static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+//yriver
+//	WARN_ON(qh->state != QH_STATE_IDLE && qh->udev);
+	WARN_ON(qh->state != UHCI_QH_STATE_IDLE && qh->udev);
+	if (!list_empty(&qh->queue))
+		dev_WARN(uhci_dev(uhci), "qh %p list not empty!\n", qh);
+
+	list_del(&qh->node);
+	if (qh->udev) {
+		qh->hep->hcpriv = NULL;
+		if (qh->dummy_td)
+			uhci_free_td(uhci, qh->dummy_td);
+	}
+	dma_pool_free(uhci->qh_pool, qh, qh->dma_handle);
+}
+
+/*
+ * When a queue is stopped and a dequeued URB is given back, adjust
+ * the previous TD link (if the URB isn't first on the queue) or
+ * save its toggle value (if it is first and is currently executing).
+ *
+ * Returns 0 if the URB should not yet be given back, 1 otherwise.
+ */
+static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh,
+		struct urb *urb)
+{
+	struct urb_priv *urbp = urb->hcpriv;
+	struct uhci_td *td;
+	int ret = 1;
+
+	/* Isochronous pipes don't use toggles and their TD link pointers
+	 * get adjusted during uhci_urb_dequeue().  But since their queues
+	 * cannot truly be stopped, we have to watch out for dequeues
+	 * occurring after the nominal unlink frame. */
+	if (qh->type == USB_ENDPOINT_XFER_ISOC) {
+		ret = (uhci->frame_number + uhci->is_stopped !=
+				qh->unlink_frame);
+		goto done;
+	}
+
+	/* If the URB isn't first on its queue, adjust the link pointer
+	 * of the last TD in the previous URB.  The toggle doesn't need
+	 * to be saved since this URB can't be executing yet. */
+	if (qh->queue.next != &urbp->node) {
+		struct urb_priv *purbp;
+		struct uhci_td *ptd;
+
+		purbp = list_entry(urbp->node.prev, struct urb_priv, node);
+		WARN_ON(list_empty(&purbp->td_list));
+		ptd = list_entry(purbp->td_list.prev, struct uhci_td,
+				list);
+		td = list_entry(urbp->td_list.prev, struct uhci_td,
+				list);
+		ptd->link = td->link;
+		goto done;
+	}
+
+	/* If the QH element pointer is UHCI_PTR_TERM then then currently
+	 * executing URB has already been unlinked, so this one isn't it. */
+	if (qh_element(qh) == UHCI_PTR_TERM)
+		goto done;
+	qh->element = UHCI_PTR_TERM;
+
+	/* Control pipes don't have to worry about toggles */
+	if (qh->type == USB_ENDPOINT_XFER_CONTROL)
+		goto done;
+
+	/* Save the next toggle value */
+	WARN_ON(list_empty(&urbp->td_list));
+	td = list_entry(urbp->td_list.next, struct uhci_td, list);
+	qh->needs_fixup = 1;
+	qh->initial_toggle = uhci_toggle(td_token(td));
+
+done:
+	return ret;
+}
+
+/*
+ * Fix up the data toggles for URBs in a queue, when one of them
+ * terminates early (short transfer, error, or dequeued).
+ */
+static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first)
+{
+	struct urb_priv *urbp = NULL;
+	struct uhci_td *td;
+	unsigned int toggle = qh->initial_toggle;
+	unsigned int pipe;
+
+	/* Fixups for a short transfer start with the second URB in the
+	 * queue (the short URB is the first). */
+	if (skip_first)
+		urbp = list_entry(qh->queue.next, struct urb_priv, node);
+
+	/* When starting with the first URB, if the QH element pointer is
+	 * still valid then we know the URB's toggles are okay. */
+	else if (qh_element(qh) != UHCI_PTR_TERM)
+		toggle = 2;
+
+	/* Fix up the toggle for the URBs in the queue.  Normally this
+	 * loop won't run more than once: When an error or short transfer
+	 * occurs, the queue usually gets emptied. */
+	urbp = list_prepare_entry(urbp, &qh->queue, node);
+	list_for_each_entry_continue(urbp, &qh->queue, node) {
+
+		/* If the first TD has the right toggle value, we don't
+		 * need to change any toggles in this URB */
+		td = list_entry(urbp->td_list.next, struct uhci_td, list);
+		if (toggle > 1 || uhci_toggle(td_token(td)) == toggle) {
+			td = list_entry(urbp->td_list.prev, struct uhci_td,
+					list);
+			toggle = uhci_toggle(td_token(td)) ^ 1;
+
+		/* Otherwise all the toggles in the URB have to be switched */
+		} else {
+			list_for_each_entry(td, &urbp->td_list, list) {
+				td->token ^= __constant_cpu_to_le32(
+							TD_TOKEN_TOGGLE);
+				toggle ^= 1;
+			}
+		}
+	}
+
+	wmb();
+	pipe = list_entry(qh->queue.next, struct urb_priv, node)->urb->pipe;
+	usb_settoggle(qh->udev, usb_pipeendpoint(pipe),
+			usb_pipeout(pipe), toggle);
+	qh->needs_fixup = 0;
+}
+
+/*
+ * Link an Isochronous QH into its skeleton's list
+ */
+static inline void link_iso(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	list_add_tail(&qh->node, &uhci->skel_iso_qh->node);
+
+	/* Isochronous QHs aren't linked by the hardware */
+}
+
+/*
+ * Link a high-period interrupt QH into the schedule at the end of its
+ * skeleton's list
+ */
+static void link_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	struct uhci_qh *pqh;
+
+	list_add_tail(&qh->node, &uhci->skelqh[qh->skel]->node);
+
+	pqh = list_entry(qh->node.prev, struct uhci_qh, node);
+	qh->link = pqh->link;
+	wmb();
+	pqh->link = LINK_TO_QH(qh);
+}
+
+/*
+ * Link a period-1 interrupt or async QH into the schedule at the
+ * correct spot in the async skeleton's list, and update the FSBR link
+ */
+static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	struct uhci_qh *pqh;
+	__le32 link_to_new_qh;
+
+	/* Find the predecessor QH for our new one and insert it in the list.
+	 * The list of QHs is expected to be short, so linear search won't
+	 * take too long. */
+	list_for_each_entry_reverse(pqh, &uhci->skel_async_qh->node, node) {
+		if (pqh->skel <= qh->skel)
+			break;
+	}
+	list_add(&qh->node, &pqh->node);
+
+	/* Link it into the schedule */
+	qh->link = pqh->link;
+	wmb();
+	link_to_new_qh = LINK_TO_QH(qh);
+	pqh->link = link_to_new_qh;
+
+	/* If this is now the first FSBR QH, link the terminating skeleton
+	 * QH to it. */
+	if (pqh->skel < SKEL_FSBR && qh->skel >= SKEL_FSBR)
+		uhci->skel_term_qh->link = link_to_new_qh;
+}
+
+/*
+ * Put a QH on the schedule in both hardware and software
+ */
+static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	WARN_ON(list_empty(&qh->queue));
+
+	/* Set the element pointer if it isn't set already.
+	 * This isn't needed for Isochronous queues, but it doesn't hurt. */
+	if (qh_element(qh) == UHCI_PTR_TERM) {
+		struct urb_priv *urbp = list_entry(qh->queue.next,
+				struct urb_priv, node);
+		struct uhci_td *td = list_entry(urbp->td_list.next,
+				struct uhci_td, list);
+
+		qh->element = LINK_TO_TD(td);
+	}
+
+	/* Treat the queue as if it has just advanced */
+	qh->wait_expired = 0;
+	qh->advance_jiffies = jiffies;
+
+	if (qh->state == QH_STATE_ACTIVE)
+		return;
+	qh->state = QH_STATE_ACTIVE;
+
+	/* Move the QH from its old list to the correct spot in the appropriate
+	 * skeleton's list */
+	if (qh == uhci->next_qh)
+		uhci->next_qh = list_entry(qh->node.next, struct uhci_qh,
+				node);
+	list_del(&qh->node);
+
+	if (qh->skel == SKEL_ISO)
+		link_iso(uhci, qh);
+	else if (qh->skel < SKEL_ASYNC)
+		link_interrupt(uhci, qh);
+	else
+		link_async(uhci, qh);
+}
+
+/*
+ * Unlink a high-period interrupt QH from the schedule
+ */
+static void unlink_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	struct uhci_qh *pqh;
+
+	pqh = list_entry(qh->node.prev, struct uhci_qh, node);
+	pqh->link = qh->link;
+	mb();
+}
+
+/*
+ * Unlink a period-1 interrupt or async QH from the schedule
+ */
+static void unlink_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	struct uhci_qh *pqh;
+	__le32 link_to_next_qh = qh->link;
+
+	pqh = list_entry(qh->node.prev, struct uhci_qh, node);
+	pqh->link = link_to_next_qh;
+
+	/* If this was the old first FSBR QH, link the terminating skeleton
+	 * QH to the next (new first FSBR) QH. */
+	if (pqh->skel < SKEL_FSBR && qh->skel >= SKEL_FSBR)
+		uhci->skel_term_qh->link = link_to_next_qh;
+	mb();
+}
+
+/*
+ * Take a QH off the hardware schedule
+ */
+static void uhci_unlink_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	if (qh->state == QH_STATE_UNLINKING)
+		return;
+	WARN_ON(qh->state != QH_STATE_ACTIVE || !qh->udev);
+	qh->state = QH_STATE_UNLINKING;
+
+	/* Unlink the QH from the schedule and record when we did it */
+	if (qh->skel == SKEL_ISO)
+		;
+	else if (qh->skel < SKEL_ASYNC)
+		unlink_interrupt(uhci, qh);
+	else
+		unlink_async(uhci, qh);
+
+	uhci_get_current_frame_number(uhci);
+	qh->unlink_frame = uhci->frame_number;
+
+	/* Force an interrupt so we know when the QH is fully unlinked */
+	if (list_empty(&uhci->skel_unlink_qh->node))
+		uhci_set_next_interrupt(uhci);
+
+	/* Move the QH from its old list to the end of the unlinking list */
+	if (qh == uhci->next_qh)
+		uhci->next_qh = list_entry(qh->node.next, struct uhci_qh,
+				node);
+	list_move_tail(&qh->node, &uhci->skel_unlink_qh->node);
+}
+
+/*
+ * When we and the controller are through with a QH, it becomes IDLE.
+ * This happens when a QH has been off the schedule (on the unlinking
+ * list) for more than one frame, or when an error occurs while adding
+ * the first URB onto a new QH.
+ */
+static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	WARN_ON(qh->state == QH_STATE_ACTIVE);
+
+	if (qh == uhci->next_qh)
+		uhci->next_qh = list_entry(qh->node.next, struct uhci_qh,
+				node);
+	list_move(&qh->node, &uhci->idle_qh_list);
+//yriver
+//	qh->state = QH_STATE_IDLE;
+	qh->state = UHCI_QH_STATE_IDLE;
+
+	/* Now that the QH is idle, its post_td isn't being used */
+	if (qh->post_td) {
+		uhci_free_td(uhci, qh->post_td);
+		qh->post_td = NULL;
+	}
+
+	/* If anyone is waiting for a QH to become idle, wake them up */
+	if (uhci->num_waiting)
+		wake_up_all(&uhci->waitqh);
+}
+
+/*
+ * Find the highest existing bandwidth load for a given phase and period.
+ */
+static int uhci_highest_load(struct uhci_hcd *uhci, int phase, int period)
+{
+	int highest_load = uhci->load[phase];
+
+	for (phase += period; phase < MAX_PHASE; phase += period)
+		highest_load = max_t(int, highest_load, uhci->load[phase]);
+	return highest_load;
+}
+
+/*
+ * Set qh->phase to the optimal phase for a periodic transfer and
+ * check whether the bandwidth requirement is acceptable.
+ */
+static int uhci_check_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	int minimax_load;
+
+	/* Find the optimal phase (unless it is already set) and get
+	 * its load value. */
+	if (qh->phase >= 0)
+		minimax_load = uhci_highest_load(uhci, qh->phase, qh->period);
+	else {
+		int phase, load;
+		int max_phase = min_t(int, MAX_PHASE, qh->period);
+
+		qh->phase = 0;
+		minimax_load = uhci_highest_load(uhci, qh->phase, qh->period);
+		for (phase = 1; phase < max_phase; ++phase) {
+			load = uhci_highest_load(uhci, phase, qh->period);
+			if (load < minimax_load) {
+				minimax_load = load;
+				qh->phase = phase;
+			}
+		}
+	}
+
+	/* Maximum allowable periodic bandwidth is 90%, or 900 us per frame */
+	if (minimax_load + qh->load > 900) {
+		dev_dbg(uhci_dev(uhci), "bandwidth allocation failed: "
+				"period %d, phase %d, %d + %d us\n",
+				qh->period, qh->phase, minimax_load, qh->load);
+		return -ENOSPC;
+	}
+	return 0;
+}
+
+/*
+ * Reserve a periodic QH's bandwidth in the schedule
+ */
+static void uhci_reserve_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	int i;
+	int load = qh->load;
+	char *p = "??";
+
+	for (i = qh->phase; i < MAX_PHASE; i += qh->period) {
+		uhci->load[i] += load;
+		uhci->total_load += load;
+	}
+	uhci_to_hcd(uhci)->self.bandwidth_allocated =
+			uhci->total_load / MAX_PHASE;
+	switch (qh->type) {
+	case USB_ENDPOINT_XFER_INT:
+		++uhci_to_hcd(uhci)->self.bandwidth_int_reqs;
+		p = "INT";
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		++uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs;
+		p = "ISO";
+		break;
+	}
+	qh->bandwidth_reserved = 1;
+	dev_dbg(uhci_dev(uhci),
+			"%s dev %d ep%02x-%s, period %d, phase %d, %d us\n",
+			"reserve", qh->udev->devnum,
+			qh->hep->desc.bEndpointAddress, p,
+			qh->period, qh->phase, load);
+}
+
+/*
+ * Release a periodic QH's bandwidth reservation
+ */
+static void uhci_release_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	int i;
+	int load = qh->load;
+	char *p = "??";
+
+	for (i = qh->phase; i < MAX_PHASE; i += qh->period) {
+		uhci->load[i] -= load;
+		uhci->total_load -= load;
+	}
+	uhci_to_hcd(uhci)->self.bandwidth_allocated =
+			uhci->total_load / MAX_PHASE;
+	switch (qh->type) {
+	case USB_ENDPOINT_XFER_INT:
+		--uhci_to_hcd(uhci)->self.bandwidth_int_reqs;
+		p = "INT";
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		--uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs;
+		p = "ISO";
+		break;
+	}
+	qh->bandwidth_reserved = 0;
+	dev_dbg(uhci_dev(uhci),
+			"%s dev %d ep%02x-%s, period %d, phase %d, %d us\n",
+			"release", qh->udev->devnum,
+			qh->hep->desc.bEndpointAddress, p,
+			qh->period, qh->phase, load);
+}
+
+static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci,
+		struct urb *urb)
+{
+	struct urb_priv *urbp;
+
+	urbp = kmem_cache_zalloc(uhci_up_cachep, GFP_ATOMIC);
+	if (!urbp)
+		return NULL;
+
+	urbp->urb = urb;
+	urb->hcpriv = urbp;
+	
+	INIT_LIST_HEAD(&urbp->node);
+	INIT_LIST_HEAD(&urbp->td_list);
+
+	return urbp;
+}
+
+static void uhci_free_urb_priv(struct uhci_hcd *uhci,
+		struct urb_priv *urbp)
+{
+	struct uhci_td *td, *tmp;
+
+	if (!list_empty(&urbp->node))
+		dev_WARN(uhci_dev(uhci), "urb %p still on QH's list!\n",
+				urbp->urb);
+
+	list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
+		uhci_remove_td_from_urbp(td);
+		uhci_free_td(uhci, td);
+	}
+
+	kmem_cache_free(uhci_up_cachep, urbp);
+}
+
+/*
+ * Map status to standard result codes
+ *
+ * <status> is (td_status(td) & 0xF60000), a.k.a.
+ * uhci_status_bits(td_status(td)).
+ * Note: <status> does not include the TD_CTRL_NAK bit.
+ * <dir_out> is True for output TDs and False for input TDs.
+ */
+static int uhci_map_status(int status, int dir_out)
+{
+	if (!status)
+		return 0;
+	if (status & TD_CTRL_BITSTUFF)			/* Bitstuff error */
+		return -EPROTO;
+	if (status & TD_CTRL_CRCTIMEO) {		/* CRC/Timeout */
+		if (dir_out)
+			return -EPROTO;
+		else
+			return -EILSEQ;
+	}
+	if (status & TD_CTRL_BABBLE)			/* Babble */
+		return -EOVERFLOW;
+	if (status & TD_CTRL_DBUFERR)			/* Buffer error */
+		return -ENOSR;
+	if (status & TD_CTRL_STALLED)			/* Stalled */
+		return -EPIPE;
+	return 0;
+}
+
+/*
+ * Control transfers
+ */
+static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
+		struct uhci_qh *qh)
+{
+	struct uhci_td *td;
+	unsigned long destination, status;
+	int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
+	int len = urb->transfer_buffer_length;
+	dma_addr_t data = urb->transfer_dma;
+	__le32 *plink;
+	struct urb_priv *urbp = urb->hcpriv;
+	int skel;
+
+	/* The "pipe" thing contains the destination in bits 8--18 */
+	destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
+
+	/* 3 errors, dummy TD remains inactive */
+	status = uhci_maxerr(3);
+	if (urb->dev->speed == USB_SPEED_LOW)
+		status |= TD_CTRL_LS;
+
+	/*
+	 * Build the TD for the control request setup packet
+	 */
+	td = qh->dummy_td;
+	uhci_add_td_to_urbp(td, urbp);
+	uhci_fill_td(td, status, destination | uhci_explen(8),
+			urb->setup_dma);
+	plink = &td->link;
+	status |= TD_CTRL_ACTIVE;
+
+	/*
+	 * If direction is "send", change the packet ID from SETUP (0x2D)
+	 * to OUT (0xE1).  Else change it from SETUP to IN (0x69) and
+	 * set Short Packet Detect (SPD) for all data packets.
+	 *
+	 * 0-length transfers always get treated as "send".
+	 */
+	if (usb_pipeout(urb->pipe) || len == 0)
+		destination ^= (USB_PID_SETUP ^ USB_PID_OUT);
+	else {
+		destination ^= (USB_PID_SETUP ^ USB_PID_IN);
+		status |= TD_CTRL_SPD;
+	}
+
+	/*
+	 * Build the DATA TDs
+	 */
+	while (len > 0) {
+		int pktsze = maxsze;
+
+		if (len <= pktsze) {		/* The last data packet */
+			pktsze = len;
+			status &= ~TD_CTRL_SPD;
+		}
+
+		td = uhci_alloc_td(uhci);
+		if (!td)
+			goto nomem;
+		*plink = LINK_TO_TD(td);
+
+		/* Alternate Data0/1 (start with Data1) */
+		destination ^= TD_TOKEN_TOGGLE;
+	
+		uhci_add_td_to_urbp(td, urbp);
+		uhci_fill_td(td, status, destination | uhci_explen(pktsze),
+				data);
+		plink = &td->link;
+
+		data += pktsze;
+		len -= pktsze;
+	}
+
+	/*
+	 * Build the final TD for control status 
+	 */
+	td = uhci_alloc_td(uhci);
+	if (!td)
+		goto nomem;
+	*plink = LINK_TO_TD(td);
+
+	/* Change direction for the status transaction */
+	destination ^= (USB_PID_IN ^ USB_PID_OUT);
+	destination |= TD_TOKEN_TOGGLE;		/* End in Data1 */
+
+	uhci_add_td_to_urbp(td, urbp);
+	uhci_fill_td(td, status | TD_CTRL_IOC,
+			destination | uhci_explen(0), 0);
+	plink = &td->link;
+
+	/*
+	 * Build the new dummy TD and activate the old one
+	 */
+	td = uhci_alloc_td(uhci);
+	if (!td)
+		goto nomem;
+	*plink = LINK_TO_TD(td);
+
+	uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
+	wmb();
+	qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
+	qh->dummy_td = td;
+
+	/* Low-speed transfers get a different queue, and won't hog the bus.
+	 * Also, some devices enumerate better without FSBR; the easiest way
+	 * to do that is to put URBs on the low-speed queue while the device
+	 * isn't in the CONFIGURED state. */
+	if (urb->dev->speed == USB_SPEED_LOW ||
+			urb->dev->state != USB_STATE_CONFIGURED)
+		skel = SKEL_LS_CONTROL;
+	else {
+		skel = SKEL_FS_CONTROL;
+		uhci_add_fsbr(uhci, urb);
+	}
+	if (qh->state != QH_STATE_ACTIVE)
+		qh->skel = skel;
+
+	urb->actual_length = -8;	/* Account for the SETUP packet */
+	return 0;
+
+nomem:
+	/* Remove the dummy TD from the td_list so it doesn't get freed */
+	uhci_remove_td_from_urbp(qh->dummy_td);
+	return -ENOMEM;
+}
+
+/*
+ * Common submit for bulk and interrupt
+ */
+static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
+		struct uhci_qh *qh)
+{
+	struct uhci_td *td;
+	unsigned long destination, status;
+	int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
+	int len = urb->transfer_buffer_length;
+	dma_addr_t data = urb->transfer_dma;
+	__le32 *plink;
+	struct urb_priv *urbp = urb->hcpriv;
+	unsigned int toggle;
+
+	if (len < 0)
+		return -EINVAL;
+
+	/* The "pipe" thing contains the destination in bits 8--18 */
+	destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
+	toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+			 usb_pipeout(urb->pipe));
+
+	/* 3 errors, dummy TD remains inactive */
+	status = uhci_maxerr(3);
+	if (urb->dev->speed == USB_SPEED_LOW)
+		status |= TD_CTRL_LS;
+	if (usb_pipein(urb->pipe))
+		status |= TD_CTRL_SPD;
+
+	/*
+	 * Build the DATA TDs
+	 */
+	plink = NULL;
+	td = qh->dummy_td;
+	do {	/* Allow zero length packets */
+		int pktsze = maxsze;
+
+		if (len <= pktsze) {		/* The last packet */
+			pktsze = len;
+			if (!(urb->transfer_flags & URB_SHORT_NOT_OK))
+				status &= ~TD_CTRL_SPD;
+		}
+
+		if (plink) {
+			td = uhci_alloc_td(uhci);
+			if (!td)
+				goto nomem;
+			*plink = LINK_TO_TD(td);
+		}
+		uhci_add_td_to_urbp(td, urbp);
+		uhci_fill_td(td, status,
+				destination | uhci_explen(pktsze) |
+					(toggle << TD_TOKEN_TOGGLE_SHIFT),
+				data);
+		plink = &td->link;
+		status |= TD_CTRL_ACTIVE;
+
+		data += pktsze;
+		len -= maxsze;
+		toggle ^= 1;
+	} while (len > 0);
+
+	/*
+	 * URB_ZERO_PACKET means adding a 0-length packet, if direction
+	 * is OUT and the transfer_length was an exact multiple of maxsze,
+	 * hence (len = transfer_length - N * maxsze) == 0
+	 * however, if transfer_length == 0, the zero packet was already
+	 * prepared above.
+	 */
+	if ((urb->transfer_flags & URB_ZERO_PACKET) &&
+			usb_pipeout(urb->pipe) && len == 0 &&
+			urb->transfer_buffer_length > 0) {
+		td = uhci_alloc_td(uhci);
+		if (!td)
+			goto nomem;
+		*plink = LINK_TO_TD(td);
+
+		uhci_add_td_to_urbp(td, urbp);
+		uhci_fill_td(td, status,
+				destination | uhci_explen(0) |
+					(toggle << TD_TOKEN_TOGGLE_SHIFT),
+				data);
+		plink = &td->link;
+
+		toggle ^= 1;
+	}
+
+	/* Set the interrupt-on-completion flag on the last packet.
+	 * A more-or-less typical 4 KB URB (= size of one memory page)
+	 * will require about 3 ms to transfer; that's a little on the
+	 * fast side but not enough to justify delaying an interrupt
+	 * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT
+	 * flag setting. */
+	td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
+
+	/*
+	 * Build the new dummy TD and activate the old one
+	 */
+	td = uhci_alloc_td(uhci);
+	if (!td)
+		goto nomem;
+	*plink = LINK_TO_TD(td);
+
+	uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
+	wmb();
+	qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
+	qh->dummy_td = td;
+
+	usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+			usb_pipeout(urb->pipe), toggle);
+	return 0;
+
+nomem:
+	/* Remove the dummy TD from the td_list so it doesn't get freed */
+	uhci_remove_td_from_urbp(qh->dummy_td);
+	return -ENOMEM;
+}
+
+static int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
+		struct uhci_qh *qh)
+{
+	int ret;
+
+	/* Can't have low-speed bulk transfers */
+	if (urb->dev->speed == USB_SPEED_LOW)
+		return -EINVAL;
+
+	if (qh->state != QH_STATE_ACTIVE)
+		qh->skel = SKEL_BULK;
+	ret = uhci_submit_common(uhci, urb, qh);
+	if (ret == 0)
+		uhci_add_fsbr(uhci, urb);
+	return ret;
+}
+
+static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb,
+		struct uhci_qh *qh)
+{
+	int ret;
+
+	/* USB 1.1 interrupt transfers only involve one packet per interval.
+	 * Drivers can submit URBs of any length, but longer ones will need
+	 * multiple intervals to complete.
+	 */
+
+	if (!qh->bandwidth_reserved) {
+		int exponent;
+
+		/* Figure out which power-of-two queue to use */
+		for (exponent = 7; exponent >= 0; --exponent) {
+			if ((1 << exponent) <= urb->interval)
+				break;
+		}
+		if (exponent < 0)
+			return -EINVAL;
+
+		/* If the slot is full, try a lower period */
+		do {
+			qh->period = 1 << exponent;
+			qh->skel = SKEL_INDEX(exponent);
+
+			/* For now, interrupt phase is fixed by the layout
+			 * of the QH lists.
+			 */
+			qh->phase = (qh->period / 2) & (MAX_PHASE - 1);
+			ret = uhci_check_bandwidth(uhci, qh);
+		} while (ret != 0 && --exponent >= 0);
+		if (ret)
+			return ret;
+	} else if (qh->period > urb->interval)
+		return -EINVAL;		/* Can't decrease the period */
+
+	ret = uhci_submit_common(uhci, urb, qh);
+	if (ret == 0) {
+		urb->interval = qh->period;
+		if (!qh->bandwidth_reserved)
+			uhci_reserve_bandwidth(uhci, qh);
+	}
+	return ret;
+}
+
+/*
+ * Fix up the data structures following a short transfer
+ */
+static int uhci_fixup_short_transfer(struct uhci_hcd *uhci,
+		struct uhci_qh *qh, struct urb_priv *urbp)
+{
+	struct uhci_td *td;
+	struct list_head *tmp;
+	int ret;
+
+	td = list_entry(urbp->td_list.prev, struct uhci_td, list);
+	if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
+
+		/* When a control transfer is short, we have to restart
+		 * the queue at the status stage transaction, which is
+		 * the last TD. */
+		WARN_ON(list_empty(&urbp->td_list));
+		qh->element = LINK_TO_TD(td);
+		tmp = td->list.prev;
+		ret = -EINPROGRESS;
+
+	} else {
+
+		/* When a bulk/interrupt transfer is short, we have to
+		 * fix up the toggles of the following URBs on the queue
+		 * before restarting the queue at the next URB. */
+		qh->initial_toggle = uhci_toggle(td_token(qh->post_td)) ^ 1;
+		uhci_fixup_toggles(qh, 1);
+
+		if (list_empty(&urbp->td_list))
+			td = qh->post_td;
+		qh->element = td->link;
+		tmp = urbp->td_list.prev;
+		ret = 0;
+	}
+
+	/* Remove all the TDs we skipped over, from tmp back to the start */
+	while (tmp != &urbp->td_list) {
+		td = list_entry(tmp, struct uhci_td, list);
+		tmp = tmp->prev;
+
+		uhci_remove_td_from_urbp(td);
+		uhci_free_td(uhci, td);
+	}
+	return ret;
+}
+
+/*
+ * Common result for control, bulk, and interrupt
+ */
+static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb)
+{
+	struct urb_priv *urbp = urb->hcpriv;
+	struct uhci_qh *qh = urbp->qh;
+	struct uhci_td *td, *tmp;
+	unsigned status;
+	int ret = 0;
+
+	list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
+		unsigned int ctrlstat;
+		int len;
+
+		ctrlstat = td_status(td);
+		status = uhci_status_bits(ctrlstat);
+		if (status & TD_CTRL_ACTIVE)
+			return -EINPROGRESS;
+
+		len = uhci_actual_length(ctrlstat);
+		urb->actual_length += len;
+
+		if (status) {
+			ret = uhci_map_status(status,
+					uhci_packetout(td_token(td)));
+			if ((debug == 1 && ret != -EPIPE) || debug > 1) {
+				/* Some debugging code */
+				dev_dbg(&urb->dev->dev,
+						"%s: failed with status %x\n",
+						__func__, status);
+
+				if (debug > 1 && errbuf) {
+					/* Print the chain for debugging */
+					uhci_show_qh(uhci, urbp->qh, errbuf,
+							ERRBUF_LEN, 0);
+					lprintk(errbuf);
+				}
+			}
+
+		/* Did we receive a short packet? */
+		} else if (len < uhci_expected_length(td_token(td))) {
+
+			/* For control transfers, go to the status TD if
+			 * this isn't already the last data TD */
+			if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
+				if (td->list.next != urbp->td_list.prev)
+					ret = 1;
+			}
+
+			/* For bulk and interrupt, this may be an error */
+			else if (urb->transfer_flags & URB_SHORT_NOT_OK)
+				ret = -EREMOTEIO;
+
+			/* Fixup needed only if this isn't the URB's last TD */
+			else if (&td->list != urbp->td_list.prev)
+				ret = 1;
+		}
+
+		uhci_remove_td_from_urbp(td);
+		if (qh->post_td)
+			uhci_free_td(uhci, qh->post_td);
+		qh->post_td = td;
+
+		if (ret != 0)
+			goto err;
+	}
+	return ret;
+
+err:
+	if (ret < 0) {
+		/* Note that the queue has stopped and save
+		 * the next toggle value */
+		qh->element = UHCI_PTR_TERM;
+		qh->is_stopped = 1;
+		qh->needs_fixup = (qh->type != USB_ENDPOINT_XFER_CONTROL);
+		qh->initial_toggle = uhci_toggle(td_token(td)) ^
+				(ret == -EREMOTEIO);
+
+	} else		/* Short packet received */
+		ret = uhci_fixup_short_transfer(uhci, qh, urbp);
+	return ret;
+}
+
+/*
+ * Isochronous transfers
+ */
+static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
+		struct uhci_qh *qh)
+{
+	struct uhci_td *td = NULL;	/* Since urb->number_of_packets > 0 */
+	int i, frame;
+	unsigned long destination, status;
+	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
+
+	/* Values must not be too big (could overflow below) */
+	if (urb->interval >= UHCI_NUMFRAMES ||
+			urb->number_of_packets >= UHCI_NUMFRAMES)
+		return -EFBIG;
+
+	/* Check the period and figure out the starting frame number */
+	if (!qh->bandwidth_reserved) {
+		qh->period = urb->interval;
+		if (urb->transfer_flags & URB_ISO_ASAP) {
+			qh->phase = -1;		/* Find the best phase */
+			i = uhci_check_bandwidth(uhci, qh);
+			if (i)
+				return i;
+
+			/* Allow a little time to allocate the TDs */
+			uhci_get_current_frame_number(uhci);
+			frame = uhci->frame_number + 10;
+
+			/* Move forward to the first frame having the
+			 * correct phase */
+			urb->start_frame = frame + ((qh->phase - frame) &
+					(qh->period - 1));
+		} else {
+			i = urb->start_frame - uhci->last_iso_frame;
+			if (i <= 0 || i >= UHCI_NUMFRAMES)
+				return -EINVAL;
+			qh->phase = urb->start_frame & (qh->period - 1);
+			i = uhci_check_bandwidth(uhci, qh);
+			if (i)
+				return i;
+		}
+
+	} else if (qh->period != urb->interval) {
+		return -EINVAL;		/* Can't change the period */
+
+	} else {
+		/* Find the next unused frame */
+		if (list_empty(&qh->queue)) {
+			frame = qh->iso_frame;
+		} else {
+			struct urb *lurb;
+
+			lurb = list_entry(qh->queue.prev,
+					struct urb_priv, node)->urb;
+			frame = lurb->start_frame +
+					lurb->number_of_packets *
+					lurb->interval;
+		}
+		if (urb->transfer_flags & URB_ISO_ASAP) {
+			/* Skip some frames if necessary to insure
+			 * the start frame is in the future.
+			 */
+			uhci_get_current_frame_number(uhci);
+			if (uhci_frame_before_eq(frame, uhci->frame_number)) {
+				frame = uhci->frame_number + 1;
+				frame += ((qh->phase - frame) &
+					(qh->period - 1));
+			}
+		}	/* Otherwise pick up where the last URB leaves off */
+		urb->start_frame = frame;
+	}
+
+	/* Make sure we won't have to go too far into the future */
+	if (uhci_frame_before_eq(uhci->last_iso_frame + UHCI_NUMFRAMES,
+			urb->start_frame + urb->number_of_packets *
+				urb->interval))
+		return -EFBIG;
+
+	status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
+	destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
+
+	for (i = 0; i < urb->number_of_packets; i++) {
+		td = uhci_alloc_td(uhci);
+		if (!td)
+			return -ENOMEM;
+
+		uhci_add_td_to_urbp(td, urbp);
+		uhci_fill_td(td, status, destination |
+				uhci_explen(urb->iso_frame_desc[i].length),
+				urb->transfer_dma +
+					urb->iso_frame_desc[i].offset);
+	}
+
+	/* Set the interrupt-on-completion flag on the last packet. */
+	td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
+
+	/* Add the TDs to the frame list */
+	frame = urb->start_frame;
+	list_for_each_entry(td, &urbp->td_list, list) {
+		uhci_insert_td_in_frame_list(uhci, td, frame);
+		frame += qh->period;
+	}
+
+	if (list_empty(&qh->queue)) {
+		qh->iso_packet_desc = &urb->iso_frame_desc[0];
+		qh->iso_frame = urb->start_frame;
+	}
+
+	qh->skel = SKEL_ISO;
+	if (!qh->bandwidth_reserved)
+		uhci_reserve_bandwidth(uhci, qh);
+	return 0;
+}
+
+static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb)
+{
+	struct uhci_td *td, *tmp;
+	struct urb_priv *urbp = urb->hcpriv;
+	struct uhci_qh *qh = urbp->qh;
+
+	list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
+		unsigned int ctrlstat;
+		int status;
+		int actlength;
+
+		if (uhci_frame_before_eq(uhci->cur_iso_frame, qh->iso_frame))
+			return -EINPROGRESS;
+
+		uhci_remove_tds_from_frame(uhci, qh->iso_frame);
+
+		ctrlstat = td_status(td);
+		if (ctrlstat & TD_CTRL_ACTIVE) {
+			status = -EXDEV;	/* TD was added too late? */
+		} else {
+			status = uhci_map_status(uhci_status_bits(ctrlstat),
+					usb_pipeout(urb->pipe));
+			actlength = uhci_actual_length(ctrlstat);
+
+			urb->actual_length += actlength;
+			qh->iso_packet_desc->actual_length = actlength;
+			qh->iso_packet_desc->status = status;
+		}
+		if (status)
+			urb->error_count++;
+
+		uhci_remove_td_from_urbp(td);
+		uhci_free_td(uhci, td);
+		qh->iso_frame += qh->period;
+		++qh->iso_packet_desc;
+	}
+	return 0;
+}
+
+static int uhci_urb_enqueue(struct usb_hcd *hcd,
+		struct urb *urb, gfp_t mem_flags)
+{
+	int ret;
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	unsigned long flags;
+	struct urb_priv *urbp;
+	struct uhci_qh *qh;
+
+	spin_lock_irqsave(&uhci->lock, flags);
+
+	ret = usb_hcd_link_urb_to_ep(hcd, urb);
+	if (ret)
+		goto done_not_linked;
+
+	ret = -ENOMEM;
+	urbp = uhci_alloc_urb_priv(uhci, urb);
+	if (!urbp)
+		goto done;
+
+	if (urb->ep->hcpriv)
+		qh = urb->ep->hcpriv;
+	else {
+		qh = uhci_alloc_qh(uhci, urb->dev, urb->ep);
+		if (!qh)
+			goto err_no_qh;
+	}
+	urbp->qh = qh;
+
+	switch (qh->type) {
+	case USB_ENDPOINT_XFER_CONTROL:
+		ret = uhci_submit_control(uhci, urb, qh);
+		break;
+	case USB_ENDPOINT_XFER_BULK:
+		ret = uhci_submit_bulk(uhci, urb, qh);
+		break;
+	case USB_ENDPOINT_XFER_INT:
+		ret = uhci_submit_interrupt(uhci, urb, qh);
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		urb->error_count = 0;
+		ret = uhci_submit_isochronous(uhci, urb, qh);
+		break;
+	}
+	if (ret != 0)
+		goto err_submit_failed;
+
+	/* Add this URB to the QH */
+	urbp->qh = qh;
+	list_add_tail(&urbp->node, &qh->queue);
+
+	/* If the new URB is the first and only one on this QH then either
+	 * the QH is new and idle or else it's unlinked and waiting to
+	 * become idle, so we can activate it right away.  But only if the
+	 * queue isn't stopped. */
+	if (qh->queue.next == &urbp->node && !qh->is_stopped) {
+		uhci_activate_qh(uhci, qh);
+		uhci_urbp_wants_fsbr(uhci, urbp);
+	}
+	goto done;
+
+err_submit_failed:
+//yriver
+//	if (qh->state == QH_STATE_IDLE)
+	if (qh->state == UHCI_QH_STATE_IDLE)
+		uhci_make_qh_idle(uhci, qh);	/* Reclaim unused QH */
+err_no_qh:
+	uhci_free_urb_priv(uhci, urbp);
+done:
+	if (ret)
+		usb_hcd_unlink_urb_from_ep(hcd, urb);
+done_not_linked:
+	spin_unlock_irqrestore(&uhci->lock, flags);
+	return ret;
+}
+
+static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	unsigned long flags;
+	struct uhci_qh *qh;
+	int rc;
+
+	spin_lock_irqsave(&uhci->lock, flags);
+	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
+	if (rc)
+		goto done;
+
+	qh = ((struct urb_priv *) urb->hcpriv)->qh;
+
+	/* Remove Isochronous TDs from the frame list ASAP */
+	if (qh->type == USB_ENDPOINT_XFER_ISOC) {
+		uhci_unlink_isochronous_tds(uhci, urb);
+		mb();
+
+		/* If the URB has already started, update the QH unlink time */
+		uhci_get_current_frame_number(uhci);
+		if (uhci_frame_before_eq(urb->start_frame, uhci->frame_number))
+			qh->unlink_frame = uhci->frame_number;
+	}
+
+	uhci_unlink_qh(uhci, qh);
+
+done:
+	spin_unlock_irqrestore(&uhci->lock, flags);
+	return rc;
+}
+
+/*
+ * Finish unlinking an URB and give it back
+ */
+static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh,
+		struct urb *urb, int status)
+__releases(uhci->lock)
+__acquires(uhci->lock)
+{
+	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
+
+	if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
+
+		/* urb->actual_length < 0 means the setup transaction didn't
+		 * complete successfully.  Either it failed or the URB was
+		 * unlinked first.  Regardless, don't confuse people with a
+		 * negative length. */
+		urb->actual_length = max(urb->actual_length, 0);
+	}
+
+	/* When giving back the first URB in an Isochronous queue,
+	 * reinitialize the QH's iso-related members for the next URB. */
+	else if (qh->type == USB_ENDPOINT_XFER_ISOC &&
+			urbp->node.prev == &qh->queue &&
+			urbp->node.next != &qh->queue) {
+		struct urb *nurb = list_entry(urbp->node.next,
+				struct urb_priv, node)->urb;
+
+		qh->iso_packet_desc = &nurb->iso_frame_desc[0];
+		qh->iso_frame = nurb->start_frame;
+	}
+
+	/* Take the URB off the QH's queue.  If the queue is now empty,
+	 * this is a perfect time for a toggle fixup. */
+	list_del_init(&urbp->node);
+	if (list_empty(&qh->queue) && qh->needs_fixup) {
+		usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+				usb_pipeout(urb->pipe), qh->initial_toggle);
+		qh->needs_fixup = 0;
+	}
+
+	uhci_free_urb_priv(uhci, urbp);
+	usb_hcd_unlink_urb_from_ep(uhci_to_hcd(uhci), urb);
+
+	spin_unlock(&uhci->lock);
+	usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb, status);
+	spin_lock(&uhci->lock);
+
+	/* If the queue is now empty, we can unlink the QH and give up its
+	 * reserved bandwidth. */
+	if (list_empty(&qh->queue)) {
+		uhci_unlink_qh(uhci, qh);
+		if (qh->bandwidth_reserved)
+			uhci_release_bandwidth(uhci, qh);
+	}
+}
+
+/*
+ * Scan the URBs in a QH's queue
+ */
+#define QH_FINISHED_UNLINKING(qh)			\
+		(qh->state == QH_STATE_UNLINKING &&	\
+		uhci->frame_number + uhci->is_stopped != qh->unlink_frame)
+
+static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	struct urb_priv *urbp;
+	struct urb *urb;
+	int status;
+
+	while (!list_empty(&qh->queue)) {
+		urbp = list_entry(qh->queue.next, struct urb_priv, node);
+		urb = urbp->urb;
+
+		if (qh->type == USB_ENDPOINT_XFER_ISOC)
+			status = uhci_result_isochronous(uhci, urb);
+		else
+			status = uhci_result_common(uhci, urb);
+		if (status == -EINPROGRESS)
+			break;
+
+		/* Dequeued but completed URBs can't be given back unless
+		 * the QH is stopped or has finished unlinking. */
+		if (urb->unlinked) {
+			if (QH_FINISHED_UNLINKING(qh))
+				qh->is_stopped = 1;
+			else if (!qh->is_stopped)
+				return;
+		}
+
+		uhci_giveback_urb(uhci, qh, urb, status);
+		if (status < 0)
+			break;
+	}
+
+	/* If the QH is neither stopped nor finished unlinking (normal case),
+	 * our work here is done. */
+	if (QH_FINISHED_UNLINKING(qh))
+		qh->is_stopped = 1;
+	else if (!qh->is_stopped)
+		return;
+
+	/* Otherwise give back each of the dequeued URBs */
+restart:
+	list_for_each_entry(urbp, &qh->queue, node) {
+		urb = urbp->urb;
+		if (urb->unlinked) {
+
+			/* Fix up the TD links and save the toggles for
+			 * non-Isochronous queues.  For Isochronous queues,
+			 * test for too-recent dequeues. */
+			if (!uhci_cleanup_queue(uhci, qh, urb)) {
+				qh->is_stopped = 0;
+				return;
+			}
+			uhci_giveback_urb(uhci, qh, urb, 0);
+			goto restart;
+		}
+	}
+	qh->is_stopped = 0;
+
+	/* There are no more dequeued URBs.  If there are still URBs on the
+	 * queue, the QH can now be re-activated. */
+	if (!list_empty(&qh->queue)) {
+		if (qh->needs_fixup)
+			uhci_fixup_toggles(qh, 0);
+
+		/* If the first URB on the queue wants FSBR but its time
+		 * limit has expired, set the next TD to interrupt on
+		 * completion before reactivating the QH. */
+		urbp = list_entry(qh->queue.next, struct urb_priv, node);
+		if (urbp->fsbr && qh->wait_expired) {
+			struct uhci_td *td = list_entry(urbp->td_list.next,
+					struct uhci_td, list);
+
+			td->status |= __cpu_to_le32(TD_CTRL_IOC);
+		}
+
+		uhci_activate_qh(uhci, qh);
+	}
+
+	/* The queue is empty.  The QH can become idle if it is fully
+	 * unlinked. */
+	else if (QH_FINISHED_UNLINKING(qh))
+		uhci_make_qh_idle(uhci, qh);
+}
+
+/*
+ * Check for queues that have made some forward progress.
+ * Returns 0 if the queue is not Isochronous, is ACTIVE, and
+ * has not advanced since last examined; 1 otherwise.
+ *
+ * Early Intel controllers have a bug which causes qh->element sometimes
+ * not to advance when a TD completes successfully.  The queue remains
+ * stuck on the inactive completed TD.  We detect such cases and advance
+ * the element pointer by hand.
+ */
+static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	struct urb_priv *urbp = NULL;
+	struct uhci_td *td;
+	int ret = 1;
+	unsigned status;
+
+	if (qh->type == USB_ENDPOINT_XFER_ISOC)
+		goto done;
+
+	/* Treat an UNLINKING queue as though it hasn't advanced.
+	 * This is okay because reactivation will treat it as though
+	 * it has advanced, and if it is going to become IDLE then
+	 * this doesn't matter anyway.  Furthermore it's possible
+	 * for an UNLINKING queue not to have any URBs at all, or
+	 * for its first URB not to have any TDs (if it was dequeued
+	 * just as it completed).  So it's not easy in any case to
+	 * test whether such queues have advanced. */
+	if (qh->state != QH_STATE_ACTIVE) {
+		urbp = NULL;
+		status = 0;
+
+	} else {
+		urbp = list_entry(qh->queue.next, struct urb_priv, node);
+		td = list_entry(urbp->td_list.next, struct uhci_td, list);
+		status = td_status(td);
+		if (!(status & TD_CTRL_ACTIVE)) {
+
+			/* We're okay, the queue has advanced */
+			qh->wait_expired = 0;
+			qh->advance_jiffies = jiffies;
+			goto done;
+		}
+		ret = 0;
+	}
+
+	/* The queue hasn't advanced; check for timeout */
+	if (qh->wait_expired)
+		goto done;
+
+	if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) {
+
+		/* Detect the Intel bug and work around it */
+		if (qh->post_td && qh_element(qh) == LINK_TO_TD(qh->post_td)) {
+			qh->element = qh->post_td->link;
+			qh->advance_jiffies = jiffies;
+			ret = 1;
+			goto done;
+		}
+
+		qh->wait_expired = 1;
+
+		/* If the current URB wants FSBR, unlink it temporarily
+		 * so that we can safely set the next TD to interrupt on
+		 * completion.  That way we'll know as soon as the queue
+		 * starts moving again. */
+		if (urbp && urbp->fsbr && !(status & TD_CTRL_IOC))
+			uhci_unlink_qh(uhci, qh);
+
+	} else {
+		/* Unmoving but not-yet-expired queues keep FSBR alive */
+		if (urbp)
+			uhci_urbp_wants_fsbr(uhci, urbp);
+	}
+
+done:
+	return ret;
+}
+
+/*
+ * Process events in the schedule, but only in one thread at a time
+ */
+static void uhci_scan_schedule(struct uhci_hcd *uhci)
+{
+	int i;
+	struct uhci_qh *qh;
+
+	/* Don't allow re-entrant calls */
+	if (uhci->scan_in_progress) {
+		uhci->need_rescan = 1;
+		return;
+	}
+	uhci->scan_in_progress = 1;
+rescan:
+	uhci->need_rescan = 0;
+	uhci->fsbr_is_wanted = 0;
+
+	uhci_clear_next_interrupt(uhci);
+	uhci_get_current_frame_number(uhci);
+	uhci->cur_iso_frame = uhci->frame_number;
+
+	/* Go through all the QH queues and process the URBs in each one */
+	for (i = 0; i < UHCI_NUM_SKELQH - 1; ++i) {
+		uhci->next_qh = list_entry(uhci->skelqh[i]->node.next,
+				struct uhci_qh, node);
+		while ((qh = uhci->next_qh) != uhci->skelqh[i]) {
+			uhci->next_qh = list_entry(qh->node.next,
+					struct uhci_qh, node);
+
+			if (uhci_advance_check(uhci, qh)) {
+				uhci_scan_qh(uhci, qh);
+				if (qh->state == QH_STATE_ACTIVE) {
+					uhci_urbp_wants_fsbr(uhci,
+	list_entry(qh->queue.next, struct urb_priv, node));
+				}
+			}
+		}
+	}
+
+	uhci->last_iso_frame = uhci->cur_iso_frame;
+	if (uhci->need_rescan)
+		goto rescan;
+	uhci->scan_in_progress = 0;
+
+	if (uhci->fsbr_is_on && !uhci->fsbr_is_wanted &&
+			!uhci->fsbr_expiring) {
+		uhci->fsbr_expiring = 1;
+		mod_timer(&uhci->fsbr_timer, jiffies + FSBR_OFF_DELAY);
+	}
+
+	if (list_empty(&uhci->skel_unlink_qh->node))
+		uhci_clear_next_interrupt(uhci);
+	else
+		uhci_set_next_interrupt(uhci);
+}
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index f3a75a9..97a22b9 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -88,6 +88,13 @@ config USB_EHCI_FSL
 	---help---
 	  Variation of ARC USB block used in some Freescale chips.
 
+config USB_EHCI_AST
+        bool "Support for ASPEED SoC EHCI USB controller"
+        depends on USB_EHCI_HCD && ARCH_ASPEED
+#        select USB_EHCI_ROOT_HUB_TT
+        ---help---
+          Variation of ARC USB block used in some ASPEED SoC chips.
+
 config USB_EHCI_HCD_PPC_OF
 	bool "EHCI support for PPC USB controller on OF platform bus"
 	depends on USB_EHCI_HCD && PPC_OF
diff --git a/drivers/usb/host/ehci-ast.c b/drivers/usb/host/ehci-ast.c
new file mode 100644
index 0000000..503df9a
--- /dev/null
+++ b/drivers/usb/host/ehci-ast.c
@@ -0,0 +1,297 @@
+/********************************************************************************
+* File Name     : drivers/usb/host/ehci-aspeed.c 
+* Author         : Ryan Chen
+* Description   : EHCI HCD (Host Controller Driver) for USB
+* 
+* Copyright (C) ASPEED Technology 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 
+    
+*   History      : 
+*    1. 2012/08/17 ryan chen create this file 
+* 
+********************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+
+
+/* ASPEED EHCI USB Host Controller */
+
+/*-------------------------------------------------------------------------*/
+
+/* configure so an HC device and id are always provided */
+/* always called with process context; sleeping is OK */
+
+static int ehci_ast_setup(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	int retval;
+
+	ehci->caps = hcd->regs;
+	ehci->regs = hcd->regs +
+		HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+	dbg_hcs_params(ehci, "reset");
+
+	/* cache this readonly data; minimize chip reads */
+	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+
+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
+	hcd->has_tt = 1;
+#else
+	hcd->has_tt = 0;
+#endif
+
+	ehci->sbrn = 0x20;
+		 
+//	retval = ehci_halt(ehci);
+//	if (retval)
+//		return retval;
+
+
+	/*
+	 * data structure init
+	 */
+	retval = ehci_init(hcd);
+	if (retval)
+		return retval;
+
+	ehci_reset(ehci);
+	ehci_port_power(ehci, 0);
+
+	return retval;
+}
+
+static const struct hc_driver ehci_ast_hc_driver = {
+	.description = hcd_name,
+	.product_desc = "ASPEED On-Chip EHCI Host Controller",
+	.hcd_priv_size = sizeof(struct ehci_hcd),
+	/*
+	 * generic hardware linkage
+	 */
+	.irq = ehci_irq,
+	.flags = HCD_USB2,
+	/*
+	 * basic lifecycle operations
+	 */
+	.reset = ehci_ast_setup,
+	.start = ehci_run,
+	.stop = ehci_stop,
+	.shutdown = ehci_shutdown,
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue = ehci_urb_enqueue,
+	.urb_dequeue = ehci_urb_dequeue,
+	.endpoint_disable = ehci_endpoint_disable,
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number = ehci_get_frame,
+	/*
+	 * root hub support
+	 */
+	.hub_status_data = ehci_hub_status_data,
+	.hub_control = ehci_hub_control,
+	.bus_suspend = ehci_bus_suspend,
+	.bus_resume = ehci_bus_resume,
+	.relinquish_port = ehci_relinquish_port,
+	.port_handed_over = ehci_port_handed_over,
+};
+
+static int ehci_ast_drv_probe(struct platform_device *pdev)
+{
+		struct resource *res;
+		struct usb_hcd *hcd;
+//		struct ehci_hcd *ehci;
+		void __iomem *regs;
+		int irq, err;
+	
+		if (usb_disabled())
+			return -ENODEV;
+
+		pr_debug("Initializing ASPEED-SoC USB Host Controller\n");
+	
+		irq = platform_get_irq(pdev, 0);
+		if (irq <= 0) {
+			dev_err(&pdev->dev,
+				"Found HC with no IRQ. Check %s setup!\n",
+				dev_name(&pdev->dev));
+			err = -ENODEV;
+			goto err1;
+		}
+
+		//TODO 
+//		IRQ_SET_HIGH_LEVEL (irq);
+//		IRQ_SET_LEVEL_TRIGGER (irq);
+	
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (!res) {
+			dev_err(&pdev->dev,
+				"Found HC with no register addr. Check %s setup!\n",
+				dev_name(&pdev->dev));
+			err = -ENODEV;
+			goto err1;
+		}
+
+		if (!request_mem_region(res->start, res->end - res->start + 1,
+					res->name)) {
+			dev_dbg(&pdev->dev, "controller already in use\n");
+			err = -EBUSY;
+			goto err1;
+		}
+
+		regs = ioremap_nocache(res->start, res->end - res->start + 1);
+		if (regs == NULL) {
+			dev_dbg(&pdev->dev, "error mapping memory\n");
+			err = -EFAULT;
+			goto err2;
+		}
+
+		hcd = usb_create_hcd(&ehci_ast_hc_driver,
+				&pdev->dev, dev_name(&pdev->dev));
+		if (!hcd) {
+			err = -ENOMEM;
+			goto err3;
+		}
+
+		hcd->rsrc_start = res->start;
+		hcd->rsrc_len = res->end - res->start + 1;
+		hcd->regs = regs;
+
+		err = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+		if (err)
+			goto err4;
+		
+		return 0;
+	
+	err4:
+		usb_put_hcd(hcd);
+	err3:
+		iounmap(regs);
+	err2:
+		release_mem_region(res->start, res->end - res->start + 1);
+	err1:
+		dev_err(&pdev->dev, "init %s fail, %d\n",
+			dev_name(&pdev->dev), err);
+	
+		return err;
+
+
+}
+
+static int ehci_ast_drv_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+	usb_remove_hcd(hcd);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+
+	return 0;	
+}
+
+ /*TBD*/
+#ifdef CONFIG_PM
+static int ehci_hcd_ast_drv_suspend(struct platform_device *pdev, pm_message_t msg)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
+	unsigned long		flags;
+	int			rc = 0;
+
+	if (time_before(jiffies, ehci->next_statechange))
+		msleep(10);
+
+	/* Root hub was already suspended. Disable irq emission and
+	 * mark HW unaccessible, bail out if RH has been resumed. Use
+	 * the spinlock to properly synchronize with possible pending
+	 * RH suspend or resume activity.
+	 *
+	 * This is still racy as hcd->state is manipulated outside of
+	 * any locks =P But that will be a different fix.
+	 */
+	spin_lock_irqsave (&ehci->lock, flags);
+	if (hcd->state != HC_STATE_SUSPENDED) {
+		rc = -EINVAL;
+		goto bail;
+	}
+	ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+	(void)ehci_readl(ehci, &ehci->regs->intr_enable);
+
+	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ bail:
+	spin_unlock_irqrestore (&ehci->lock, flags);
+
+	// could save FLADJ in case of Vaux power loss
+	// ... we'd only use it to handle clock skew
+
+	return rc;
+}
+static int ehci_hcd_ast_drv_resume(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
+
+	// maybe restore FLADJ
+
+	if (time_before(jiffies, ehci->next_statechange))
+		msleep(100);
+
+	/* Mark hardware accessible again as we are out of D3 state by now */
+	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+	usb_root_hub_lost_power(hcd->self.root_hub);
+
+	/* Else reset, to cope with power loss or flush-to-storage
+	 * style "resume" having let BIOS kick in during reboot.
+	 */
+	(void) ehci_halt(ehci);
+	(void) ehci_reset(ehci);
+
+	/* emptying the schedule aborts any urbs */
+	spin_lock_irq(&ehci->lock);
+	if (ehci->reclaim)
+		end_unlink_async(ehci);
+	ehci_work(ehci);
+	spin_unlock_irq(&ehci->lock);
+
+	ehci_writel(ehci, ehci->command, &ehci->regs->command);
+	ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
+	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
+
+	/* here we "know" root ports should always stay powered */
+	ehci_port_power(ehci, 1);
+
+	hcd->state = HC_STATE_SUSPENDED;
+	return 0;
+}
+#endif
+
+MODULE_ALIAS("platform:ehci_ast");
+
+static struct platform_driver ehci_hcd_ast_driver = {
+	.probe = ehci_ast_drv_probe,
+	.remove = ehci_ast_drv_remove,
+	.shutdown = usb_hcd_platform_shutdown,
+#ifdef CONFIG_PM	
+	.suspend      	= ehci_hcd_ast_drv_suspend,
+	.resume       	= ehci_hcd_ast_drv_resume,
+#endif	
+	.driver = {
+		.name	= "ehci-ast",
+	},
+};
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index e551bb3..a34a4cf 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -581,6 +581,7 @@ static int ehci_run (struct usb_hcd *hcd)
 	 * Scsi_Host.highmem_io, and so forth.  It's readonly to all
 	 * host side drivers though.
 	 */
+
 	hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
 	if (HCC_64BIT_ADDR(hcc_params)) {
 		ehci_writel(ehci, 0, &ehci->regs->segment);
@@ -1036,6 +1037,11 @@ MODULE_LICENSE ("GPL");
 #define	PLATFORM_DRIVER		ixp4xx_ehci_driver
 #endif
 
+#ifdef CONFIG_USB_EHCI_AST
+#include "ehci-ast.c"
+#define	PLATFORM_DRIVER		ehci_hcd_ast_driver
+#endif
+
 #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
     !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER)
 #error "missing bus glue for ehci-hcd"
@@ -1117,7 +1123,10 @@ err_debug:
 	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 	return retval;
 }
-module_init(ehci_hcd_init);
+
+//ehci must after uhci driver module load. Ryan Modify
+late_initcall(ehci_hcd_init);
+//module_init(ehci_hcd_init);
 
 static void __exit ehci_hcd_cleanup(void)
 {
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3f3ce13..a8be29b 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1473,6 +1473,30 @@ config FB_SAVAGE_ACCEL
           the resulting framebuffer console has bothersome glitches, then
           choose N here.
 
+menuconfig FB_AST
+        tristate "ASPEED Framebuffer Driver"
+        depends on FB
+        select FB_CFB_FILLRECT
+        select FB_CFB_COPYAREA
+        select FB_CFB_IMAGEBLIT
+        default n
+
+if FB_AST
+
+config AST_DAC
+        bool "CRT DAC output"
+
+config AST_DVO
+        bool "CRT DVO output"
+
+config HDMI_CAT6613
+       bool "Enable CAT6613 HDMI TX"
+       depends on FB_AST && AST_DVO
+       help
+          This option will support CAT6613 HDMI TX driver
+
+endif
+
 config FB_SIS
 	tristate "SiS/XGI display support"
 	depends on FB && PCI
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index e39e33e..97bc000 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -41,6 +41,8 @@ obj-$(CONFIG_FB_NVIDIA)		  += nvidia/
 obj-$(CONFIG_FB_ATY)		  += aty/ macmodes.o
 obj-$(CONFIG_FB_ATY128)		  += aty/ macmodes.o
 obj-$(CONFIG_FB_RADEON)		  += aty/
+obj-$(CONFIG_FB_AST)              += astfb.o
+obj-$(CONFIG_HDMI_CAT6613)	  += hdmi_cat6613.o
 obj-$(CONFIG_FB_SIS)		  += sis/
 obj-$(CONFIG_FB_VIA)		  += via/
 obj-$(CONFIG_FB_KYRO)             += kyro/
diff --git a/drivers/video/astfb.c b/drivers/video/astfb.c
new file mode 100644
index 0000000..8292bb8
--- /dev/null
+++ b/drivers/video/astfb.c
@@ -0,0 +1,1056 @@
+ /********************************************************************************
+* File Name     : drivers/video/astfb.c
+* Author         : Ryan Chen
+* Description   : ASPEED Framebuffer Driver 
+*
+* Copyright (C) ASPEED Tech. 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
+
+*   History      :
+*    1. 2012/12/27 Ryan Chen create this file
+*        
+*
+********************************************************************************/
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/mach/map.h>
+#include <plat/regs-crt.h>
+#include <mach/ast_lcd.h>
+
+#ifdef  CONFIG_DOUBLE_BUFFER
+#define NUMBER_OF_BUFFERS 2
+#else
+#define NUMBER_OF_BUFFERS 1
+#endif
+
+//////////////////////////////////////////////////////////////
+/* H/W Feature Definition */
+#define DEFAULT_MMIO_SIZE		0x00020000
+#define DEFAULT_CMDQ_SIZE		0x00100000
+#define MIN_CMDQ_SIZE			0x00040000
+#define CMD_QUEUE_GUARD_BAND		0x00000020
+#define DEFAULT_HWC_NUM			0x00000002
+
+////////////////////////////////////////////////////////////////
+static wait_queue_head_t wq;
+static int gNoPanDisplay;
+static int gGUIWaitVsync;
+
+#define ASTFB_GET_DFBINFO       _IOR(0xF3,0x00,struct astfb_dfbinfo)
+
+/* Default Threshold Seting */
+#define CRT_LOW_THRESHOLD_VALUE         0x12
+#define CRT_HIGH_THRESHOLD_VALUE        0x1E
+
+//#define    CRT_LOW_THRESHOLD_VALUE             0x60
+//#define    CRT_HIGH_THRESHOLD_VALUE            0x78
+//for fix 1920X1080
+//#define    CRT_LOW_THRESHOLD_VALUE             0x16
+//#define    CRT_HIGH_THRESHOLD_VALUE            0x1E
+
+////////////////////////////////////////////////////////////
+
+/* Debugging stuff */
+
+#define FBDBG 1
+
+#define dprintk(msg...) if (FBDBG) { printk(KERN_DEBUG "astfb: " msg); }
+
+struct pixel_freq_pll_data {
+	u32 pixel_freq; //*10000
+	u32 pll_set;
+};
+
+static struct pixel_freq_pll_data pll_table[] = {
+	{39721, 	0x00046515}, 	/* 00: VCLK25_175	*/		
+	{35308, 	0x00047255},	/* 01: VCLK28_322	*/
+	{31746,  	0x0004682a},	/* 02: VCLK31_5 		*/
+	{27777, 	0x0004672a},	/* 03: VCLK36		*/	
+	{25000,  	0x00046c50},	/* 04: VCLK40		*/
+	{20202,		0x00046842},	/* 05: VCLK49_5 	*/
+	{20000,		0x00006c32},	/* 06: VCLK50			*/
+	{17777,		0x00006a2f},	/* 07: VCLK56_25		*/
+	{15384,		0x00006c41},	/* 08: VCLK65		*/
+	{13333,		0x00006832},	/* 09: VCLK75			*/
+	{12690,		0x0000672e},	/* 0A: VCLK78_75		*/
+	{10582,		0x0000683f},	/* 0B: VCLK94_5 		*/
+	{9259,		0x00004824},	/* 0C: VCLK108			*/
+	{7407,		0x0000482d},	/* 0D: VCLK135			*/
+	{6349,		0x0000472e},	/* 0E: VCLK157_5		*/
+	{6172,		0x00004836},	/* 0F: VCLK162			*/
+};
+
+// ARGB4444 format
+unsigned short cursor_8x8[] = {
+	0x0FFF, 0x1FFF, 0x2FFF, 0x3777, 0x4777, 0x5777, 0x6777, 0x7888, 
+	0x8FFF, 0xF000, 0xAFFF, 0xB777, 0xC777, 0xD777, 0xE777, 0xF888, 
+	0x0FFF, 0x1FFF, 0x2FFF, 0x3FFF, 0x4777, 0x5777, 0x6777, 0x7888, 
+	0x8FFF, 0x9FFF, 0xAFFF, 0xBFFF, 0xCFFF, 0xD777, 0xE777, 0xF888, 
+	0x0FFF, 0x1FFF, 0x2FFF, 0x3FFF, 0x4FFF, 0x5FFF, 0x6FFF, 0x7888, 
+	0x8FFF, 0x9FFF, 0xAFFF, 0xBFFF, 0xCFFF, 0xDFFF, 0xEFFF, 0xFFFF, 
+	0x0FFF, 0x1FFF, 0x2777, 0x3FFF, 0x4FFF, 0x5FFF, 0x6FFF, 0x7FFF, 
+	0x8FFF, 0x9777, 0xA777, 0xB777, 0xC777, 0xDFFF, 0xEFFF, 0xFFFF, 
+};
+
+// XRGB4444 format
+unsigned short cursor_16x16[] = {
+	0x8777, 0x8777, 0x8777, 0x8777, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0x8777, 0xC888, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0x8777, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0x8777, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0x8777, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0x4777, 0x4FFF, 0x4FFF, 0x4FFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0x4FFF, 0x4FFF, 0x4FFF, 0x4FFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0x0FFF, 0x0FFF, 0x0FFF, 0x0FFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0x0FFF, 0x0FFF, 0x0FFF, 0x0FFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0x0FFF, 0x0FFF, 0x0FFF, 0x0FFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0x0FFF, 0x0FFF, 0x0FFF, 0x0FFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0xCFFF, 0xCFFF, 0xCFFF, 0xCFFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0xCFFF, 0xCFFF, 0xCFFF, 0xCFFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0xCFFF, 0xCFFF, 0xCFFF, 0xCFFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0xCFFF, 0xCFFF, 0xCFFF, 0xCFFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+	0xCFFF, 0xCFFF, 0xCFFF, 0xCFFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 
+};
+
+struct astfb_device {
+	int					state;
+	struct mutex		rqueue_mutex;
+	int					palette_size;
+	u32					pseudo_palette[17];
+	struct platform_device 		*pdev;
+	struct fb_var_screeninfo	new_var;	/* for mode changes */
+};
+
+
+/* data structure */
+struct astfb_info {
+	struct platform_device 	*pdev;
+	struct fb_info			*info;
+	struct resource *reg_res;
+	struct resource *fb_res;
+	void __iomem *base;
+	int addr_assign;
+	int irq;
+	int yuv_mode;
+	u32 pseudo_palette[17];
+	
+	struct timer_list timer;
+
+	/* driver registered */
+	int registered;	
+	/* console control */	
+	int currcon;
+
+	int need_wakeup;
+	void __iomem *next_addr;
+
+
+	u8 hwcursor;   //0: disable , 1 : enable
+	u8 dac;	//0: disable , 1 : enable
+	u8 dvo;	//0: disable , 1 : enable
+	u8 xmiter;	//0: dvi, 1:hdmi;	
+	struct ast_fb_plat_data *fb_plat_data;
+	 
+};
+
+static inline void
+astfb_write(struct astfb_info *fbinfo, u32 val, u32 reg)
+{
+//	dprintk("astfb_write : val: %x , reg : %x \n",val,reg);	
+	writel(val, fbinfo->base+ reg);
+}
+
+static inline u32
+astfb_read(struct astfb_info *fbinfo, u32 reg)
+{
+	return readl(fbinfo->base + reg);
+}
+
+static void astfb_osd_enable(struct astfb_info *sfb, u8 enable)
+{
+	if(enable)
+		astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) | CRT_CTRL_OSD_EN, AST_CRT_CTRL1);
+	else
+		astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) & ~CRT_CTRL_OSD_EN, AST_CRT_CTRL1);
+}
+
+static void astfb_cursor_enable(struct astfb_info *sfb, u8 enable)
+{
+	if(enable) {
+		astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) | CRT_CTRL_HW_CURSOR_EN, AST_CRT_CTRL1);
+	} else {
+		astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) & ~CRT_CTRL_HW_CURSOR_EN, AST_CRT_CTRL1);
+	}
+}
+
+int
+astfb_crtc_to_var(struct fb_var_screeninfo *var, struct astfb_info *sfb)
+{
+    
+    /* crtc */
+    var->xoffset = var->yoffset = 0;
+    
+    /* palette */
+    switch(var->bits_per_pixel) {
+    case 8:
+       var->red.offset = var->green.offset = var->blue.offset = 0;
+       var->red.length = var->green.length = var->blue.length = 6;
+       break;
+    case 16:
+       var->red.offset = 11;
+       var->red.length = 5;
+       var->green.offset = 5;
+       var->green.length = 6;
+       var->blue.offset = 0;
+       var->blue.length = 5;
+       var->transp.offset = 0;
+       var->transp.length = 0;
+       break;
+	case 24:
+    case 32:
+       var->red.offset = 16;
+       var->red.length = 8;
+       var->green.offset = 8;
+       var->green.length = 8;
+       var->blue.offset = 0;
+       var->blue.length = 8;
+       var->transp.offset = 24;
+       var->transp.length = 8;
+       break;
+    }
+    
+    var->red.msb_right = 
+    var->green.msb_right =
+    var->blue.msb_right =
+    var->transp.offset = 
+    var->transp.length =  
+    var->transp.msb_right = 0;
+	    
+    return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static int astfb_hw_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+//	printk("astfb_hw_cursor \n");
+	return 0;
+}
+
+#if (NUMBER_OF_BUFFERS > 1)
+static int astfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info)
+{
+	struct astfb_info *sfb = info->par;
+	u32 addr;
+	s32 timeout;
+	
+	if(gNoPanDisplay)
+			return 0;
+	
+	addr = var->yoffset * info->fix.line_length + info->fix.smem_start;
+	
+	astfb_write(sfb, addr, AST_CRT_ADDR);
+	
+	if(gGUIWaitVsync)
+	{
+		timeout = interruptible_sleep_on_timeout(&wq,HZ/60);
+		if(timeout<0)
+				dprintk("%s: interruptible_sleep_on_timeout, may lost interrupt! timeout=%d\n",__FUNCTION__,timeout);
+	}
+	return 0;
+
+} /* astfb_pan_display */
+#endif
+
+static int astfb_set_par(struct fb_info *info)
+{
+	struct astfb_info *sfb = info->par;
+	struct fb_var_screeninfo *var = &info->var;
+	u32 i,ctrl1, ctrl2, htt, hde, hrs_s, hrs_e, vtt, vde, vrs_s, vrs_e;
+	u32 d_offset, t_count, thshld;
+	u32 d2_pll;
+	
+	//S1  : set H / V 
+	//  Horizontal Timing
+	htt = var->xres + var->left_margin + var->right_margin + var->hsync_len;
+	hde = var->xres;	
+	astfb_write(sfb, CRT_H_TOTAL((htt - 1)) | CRT_H_DE((hde - 1)), AST_CRT_HORIZ0);
+
+	hrs_s = var->xres + var->right_margin;
+	hrs_e = var->xres + var->right_margin + var->hsync_len;
+	astfb_write(sfb, CRT_H_RS_START((hrs_s - 1)) | CRT_H_RS_END((hrs_e - 1)), AST_CRT_HORIZ1);
+
+	dprintk("var->upper_margin= %d, var->lower_margin= %d, var->vsync_len = %d \n",var->upper_margin, var->lower_margin, var->vsync_len);
+
+	vtt = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
+	vde = var->yres;
+	astfb_write(sfb, CRT_V_TOTAL((vtt - 1)) | CRT_V_DE((vde - 1)), AST_CRT_VERTI0);	
+	vrs_s = var->yres + var->lower_margin;
+	vrs_e = var->yres + var->lower_margin + var->vsync_len;
+	astfb_write(sfb, CRT_V_RS_START((vrs_s - 1)) | CRT_V_RS_END((vrs_e - 1)), AST_CRT_VERTI1);
+
+	if(var->nonstd != 0)
+		printk("TODO Check .... nonstd \n");
+	
+	switch (var->nonstd) {
+	case 0:
+		break;
+	case ASTFB_COLOR_YUV444:
+		var->bits_per_pixel = 32;
+		return 0;
+	case ASTFB_COLOR_YUV420:
+		var->bits_per_pixel = 32;
+		return 0;
+	}
+
+	//S2 : Offset , TODO ... (x + 0x1f) & ~0x1f
+	d_offset = var->xres * var->bits_per_pixel /8;
+//	dprintk("d_offset %d\n",d_offset);
+
+	switch (var->nonstd) {
+	case 0:
+		break;
+	case ASTFB_COLOR_YUV444:
+		var->bits_per_pixel = 24;
+		return 0;
+	case ASTFB_COLOR_YUV420:
+		var->bits_per_pixel = 16;
+		return 0;
+	}
+
+	t_count =(var->xres * var->bits_per_pixel + 63) / 64;
+//	dprintk("t_count %d \n",t_count);
+	astfb_write(sfb, CRT_DISP_OFFSET(d_offset) | CRT_TERM_COUNT(t_count), AST_CRT_OFFSET);
+
+
+	//S3 : DCLK
+	dprintk("var->pixclock = %d \n",var->pixclock);
+
+	for(i=0; i<sizeof(pll_table)/sizeof(struct pixel_freq_pll_data); i++) {
+		if(pll_table[i].pixel_freq == var->pixclock) {
+			astfb_write(sfb, pll_table[i].pll_set, AST_CRT_PLL);
+			dprintk("find pixclk in table set 0x%x \n",pll_table[i].pll_set);
+			break;
+		}
+	}
+	if(i == sizeof(pll_table)/sizeof(struct pixel_freq_pll_data))
+		printk("ERROR pixclk in table ... FIXME \n");
+#if 0	
+	d2_pll = sfb->fb_plat_data->get_clk();
+	u32 num, denum, div0,
+	num = pll_table[i].pll_set & 0xff;
+	denum = (pll_table[i].pll_set >> 8) & 0x1f;
+	div0 = (pll_table[i].pll_set >> 13) & 0x3;
+	div1 = (pll_table[i].pll_set >> 13) & 0x3;
+	printk
+#endif
+
+	//S4
+	astfb_write(sfb, sfb->info->fix.smem_start, AST_CRT_ADDR);
+
+	thshld = CRT_THROD_HIGH(CRT_HIGH_THRESHOLD_VALUE) | CRT_THROD_LOW(CRT_LOW_THRESHOLD_VALUE);
+	astfb_write(sfb, thshld, AST_CRT_THROD);
+
+	
+	info->fix.line_length = (var->xres*var->bits_per_pixel)/8;
+	dprintk("x :%d , y : %d , bpp = %d \n",var->xres, var->yres, var->bits_per_pixel);
+	//disable crt first .....
+	astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL2) & ~(CRT_CTRL_DAC_PWR_EN | CRT_CTRL_DVO_EN), AST_CRT_CTRL2);
+
+	ctrl1 = astfb_read(sfb, AST_CRT_CTRL1);
+	//CTRL 1 
+	//  SetPolarity
+	dprintk("var->sync : %x , var->vmode = %d \n",var->sync, var->vmode);
+	
+	if(var->sync & FB_SYNC_HOR_HIGH_ACT)
+		ctrl1 &= ~CRT_CTRL_HSYNC_POLARITY;
+	else
+		ctrl1 |= CRT_CTRL_HSYNC_POLARITY;
+	
+	if(var->sync & FB_SYNC_VERT_HIGH_ACT)
+		ctrl1 &= ~CRT_CTRL_VSYNC_POLARITY;
+	else
+		ctrl1 |= CRT_CTRL_VSYNC_POLARITY;
+	
+    /* Mode Type Setting */
+	
+	if(var->bits_per_pixel==16)
+		ctrl1 &= ~CRT_CTRL_FORMAT_MASK;	//RGB565
+	else
+		ctrl1 |= CRT_CTRL_FORMAT(COLOR_XRGB8888);
+
+	if (var->vmode & FB_VMODE_INTERLACED)
+		ctrl1 |= CRT_CTRL_INTER_TIMING;
+	else
+		ctrl1 &= ~CRT_CTRL_INTER_TIMING;
+	
+	//enable crt ...
+	astfb_write(sfb, ctrl1 | CRT_CTRL_GRAPHIC_EN, AST_CRT_CTRL1);
+
+	dprintk("var->left_margin= %d, var->right_margin= %d, var->hsync_len = %d \n",var->left_margin, var->right_margin, var->hsync_len);
+
+
+	//enable dac / dvo
+	//CTRL 2 
+	ctrl2 = 0;//astfb_read(sfb, AST_CRT_CTRL2);
+
+	// SoC V2 add CRT interrupt support. We should not touch this setting when changing video timing.
+	ctrl2 &= ~CRT_CTRL_VLINE_NUM_MASK;
+
+#ifdef CONFIG_AST_DAC
+	ctrl2 |= CRT_CTRL_DAC_PWR_EN;
+#endif
+
+#ifdef CONFIG_AST_DVO
+	ctrl2 |= CRT_CTRL_DVO_EN;
+#endif
+
+	astfb_write(sfb, ctrl2 , AST_CRT_CTRL2);
+	
+	return 0;
+}
+
+static int astfb_get_cmap_len(struct fb_var_screeninfo *var)
+{
+	return (var->bits_per_pixel == 8) ? 256 : 16;
+}
+
+static int astfb_setcolreg(unsigned regno, 
+							unsigned red, unsigned green, unsigned blue,
+							unsigned transp, struct fb_info *info)
+{
+	if(regno >= astfb_get_cmap_len(&info->var))
+		return 1;
+      
+	switch(info->var.bits_per_pixel) {
+	case 8:
+		return 1;
+		break;
+	case 16:
+		((u32 *)(info->pseudo_palette))[regno] =
+				(red & 0xf800)          |
+				((green & 0xfc00) >> 5) |
+				((blue & 0xf800) >> 11);
+		break;
+	case 24:
+	case 32:
+		red >>= 8;
+		green >>= 8;
+		blue >>= 8;
+		((u32 *)(info->pseudo_palette))[regno] =
+				(red << 16) | (green << 8) | (blue);
+		break;
+	}
+	return 0;
+
+}
+
+/*
+ * Blank the screen if blank_mode != 0, else unblank. Return 0 if blanking
+ * succeeded, != 0 if un-/blanking failed.
+ * blank_mode == 2: suspend vsync
+ * blank_mode == 3: suspend hsync
+ * blank_mode == 4: powerdown
+ */
+static int astfb_blank(int blank_mode, struct fb_info *info)
+{
+	u32 ctrl;
+	struct astfb_info *sfb = info->par;
+
+	printk(KERN_DEBUG "astfb: astfb_blank mode %d \n",blank_mode);
+	ctrl = astfb_read(sfb, AST_CRT_CTRL1);
+		
+	switch(blank_mode) {
+		case FB_BLANK_UNBLANK:	/* on */
+			ctrl &= ~CRT_CTRL_SCREEN_OFF;
+		break;
+		case FB_BLANK_NORMAL:	/* blank */
+			ctrl |= CRT_CTRL_SCREEN_OFF;
+		break;
+		case FB_BLANK_VSYNC_SUSPEND:	/* no vsync */
+			ctrl |= CRT_CTRL_VSYNC_OFF;
+		break;
+		case FB_BLANK_HSYNC_SUSPEND:	/* no hsync */
+			ctrl |= CRT_CTRL_HSYNC_OFF;
+		break;
+		case FB_BLANK_POWERDOWN:	/* off */
+			ctrl |= (CRT_CTRL_SCREEN_OFF | CRT_CTRL_VSYNC_OFF | CRT_CTRL_HSYNC_OFF);
+		break;
+		default:
+			return 1;
+	}	
+
+    /* set reg */
+	astfb_write(sfb, ctrl, AST_CRT_CTRL1);
+	
+	return 0;
+
+} /* astfb_blank */
+
+static int astfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	var->xres_virtual = var->xres;
+	var->yres_virtual =var->yres * NUMBER_OF_BUFFERS;
+////////////////////////////////////////////////////////////////////
+	/* Sanity check for offsets */
+	if(var->xoffset < 0) var->xoffset = 0;
+	if(var->yoffset < 0) var->yoffset = 0;
+
+	if(var->xres > var->xres_virtual)
+		var->xres_virtual = var->xres;
+
+	/* Truncate offsets to maximum if too high */
+	if(var->xoffset > var->xres_virtual - var->xres) {
+		var->xoffset = var->xres_virtual - var->xres - 1;
+	}
+
+	if(var->yoffset > var->yres_virtual - var->yres) {
+		var->yoffset = var->yres_virtual - var->yres - 1;
+	}
+////////////////////////////////////////////////////////////////////	        
+	switch(var->bits_per_pixel) {
+		case 8:
+			var->red.offset = var->green.offset = var->blue.offset = 0;
+			var->red.length = var->green.length = var->blue.length = 6;
+			break;
+		case 16:
+			var->red.offset = 11;
+			var->red.length = 5;
+			var->green.offset = 5;
+			var->green.length = 6;
+			var->blue.offset = 0;
+			var->blue.length = 5;
+			var->transp.offset = 0;
+			var->transp.length = 0;
+			break;
+		case 24:
+		case 32:
+			var->red.offset = 16;
+			var->red.length = 8;
+			var->green.offset = 8;
+			var->green.length = 8;
+			var->blue.offset = 0;
+			var->blue.length = 8;
+			var->transp.length = 8;
+			var->transp.offset = 24;
+			break;
+		default:
+			dprintk("bpp=%d not support\n",var->bits_per_pixel);
+			return -EINVAL;
+			break;
+	}
+	return 0;
+}
+
+static int
+astfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+{
+	struct astfb_info *sfb = info->par;
+	
+	printk(KERN_DEBUG "astfb: astfb_ioctl is called \n");
+
+	switch(cmd) {
+//	   case AST_COLOR_FORMAT:
+//	        return 0;
+
+           default:
+	        return -EINVAL;           
+        }
+
+	return 0;
+	
+} /* astfb_ioctl */
+
+/* fb ops */
+static struct fb_ops astfb_ops = {
+	.owner          = THIS_MODULE,
+	.fb_check_var   = astfb_check_var,
+	.fb_set_par     = astfb_set_par,
+    .fb_blank       = astfb_blank,
+	.fb_setcolreg   = astfb_setcolreg,    
+	.fb_fillrect    = cfb_fillrect,
+	.fb_copyarea    = cfb_copyarea,
+	.fb_imageblit   = cfb_imageblit,
+    .fb_ioctl       = astfb_ioctl,
+    .fb_cursor		= astfb_hw_cursor,
+#if (NUMBER_OF_BUFFERS > 1)    
+    .fb_pan_display = astfb_pan_display,    
+#endif
+};
+
+static void ast_fbmem_free(struct astfb_info *sfb)
+{
+	iounmap(sfb->info->screen_base);
+}
+
+static irqreturn_t
+astfb_isr(int irq, void *parm)
+{
+    u32 status;
+    struct astfb_info *sfb=parm;
+    status = astfb_read(sfb, AST_CRT_CTRL1);
+    astfb_write(sfb, status, AST_CRT_CTRL1);
+    if (status & CRT_CTRL_VERTICAL_INTR_STS)
+            wake_up_interruptible(&wq);
+
+    return IRQ_HANDLED;
+}
+
+//TODO ..
+static int astfb_setup(struct astfb_info *sfb)
+{
+	char *this_opt = NULL;
+	char *options = NULL;
+	char tmp[128];
+	char *tmp_opt;
+	char name[10];
+	int i;
+	
+	fb_get_options("astfb", &options);
+	dprintk("%s\n", options);
+
+	if (!options || !*options)
+		return -1;
+
+	strcpy(tmp, options);
+	tmp_opt=tmp;
+	while ((this_opt = strsep(&tmp_opt, ",")) != NULL) {
+		printk("x %s \n",this_opt);
+		if (!strncmp(this_opt, "mode:", 5)) {
+				printk("%s \n",this_opt);		
+		} else if(!strncmp(this_opt, "hwcursor:", 9)) {
+				printk("%s \n",this_opt);
+		} else if(!strncmp(this_opt, "osd:", 4)) {
+				printk("%s \n",this_opt);
+		} else if (!strncmp(this_opt, "vram:", 8)) {
+				printk("%s \n",this_opt);
+		} else if(!strncmp(this_opt, "dac:", 4)) {
+				printk("%s \n",this_opt);
+		} else if(!strncmp(this_opt, "dvo:", 4)) {
+				printk("%s \n",this_opt);				
+		} else {
+			printk("f %s \n",this_opt);
+		}
+		
+	}
+
+    return 0;
+    	
+} /* astfb_setup */
+
+static void sfb_timer(unsigned long private)
+{
+    struct astfb_info *sfb = (void *) private;
+    if(sfb->need_wakeup)
+    {
+        sfb->need_wakeup=0;
+        wake_up_interruptible(&wq);
+    }
+    if(sfb->next_addr)
+    {
+		astfb_write(sfb, (u32)sfb->next_addr, AST_CRT_ADDR);
+        sfb->need_wakeup=1;
+    }
+    mod_timer(&sfb->timer, jiffies + HZ/24);
+}
+
+#ifdef CONFIG_HDMI_CAT6613
+static ssize_t show_hdmi_status(struct device *device,
+                             struct device_attribute *attr, char *buf)
+{
+    struct fb_info *fb_info = dev_get_drvdata(device);
+    ssize_t len = 0;
+    int rc;
+
+    rc=ast_hdmi_get_info(fb_info);
+    if(rc==1)
+            len=sprintf(buf, "UNPLUG\n");
+    else if(rc==0)
+            len=sprintf(buf, "PLUG\n");
+    else
+            len=sprintf(buf, "UNKNOWN\n");
+    return len;
+}
+
+static ssize_t show_hdmi_enable(struct device *device,
+                             struct device_attribute *attr, char *buf)
+{
+    struct fb_info *info = dev_get_drvdata(device);
+    struct astfb_info *sfb = info->par;
+
+    return sprintf(buf, "%d\n",sfb->hdmi_en);
+}
+
+static ssize_t store_hdmi_enable(struct device *device,
+                                           struct device_attribute *attr,
+                                           const char *buf, size_t count)
+{
+    struct fb_info *info = dev_get_drvdata(device);
+    struct astfb_info *sfb = info->par;
+    if(buf[0]=='1') {
+            ast_hdmi_enable(1);
+            sfb->hdmi_en=1;
+    }
+    else {
+            ast_hdmi_enable(0);
+            sfb->hdmi_en=0;
+    }
+
+    return count;
+}
+#endif
+
+static ssize_t show_lcd_enable(struct device *device,
+                             struct device_attribute *attr, char *buf)
+{
+    struct fb_info *info = dev_get_drvdata(device);
+    struct astfb_info *sfb = info->par;
+    if(astfb_read(sfb, AST_CRT_CTRL1) & CRT_CTRL_GRAPHIC_EN)
+            return sprintf(buf, "%d\n",1);
+    else
+            return sprintf(buf, "%d\n",0);
+}
+
+static ssize_t store_lcd_enable(struct device *device,
+                                           struct device_attribute *attr,
+                                           const char *buf, size_t count)
+{
+    struct fb_info *info = dev_get_drvdata(device);
+    struct astfb_info *sfb = info->par;
+    if(buf[0]=='1') {
+        astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) | CRT_CTRL_GRAPHIC_EN, AST_CRT_CTRL1);
+    }
+    else {
+        astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) & ~CRT_CTRL_GRAPHIC_EN, AST_CRT_CTRL1);
+    }
+
+    return count;
+}
+
+static ssize_t show_pix_clk(struct device *device,
+                             struct device_attribute *attr, char *buf)
+{
+        struct fb_info *info = dev_get_drvdata(device);
+        struct astfb_info *sfb = info->par;
+
+//        return sprintf(buf, "target_clk=%d\ncalc_clk=%d\n",sfb->target_clk,sfb->calc_clk);
+}
+
+static ssize_t no_pan_display_show(struct device *device,
+                             struct device_attribute *attr, char *buf)
+{
+        return sprintf(buf, "%hu\n", gNoPanDisplay);
+}
+
+static ssize_t no_pan_display_store(struct device *device,
+                                           struct device_attribute *attr,
+                                           const char *buf, size_t count)
+{
+        unsigned short value;
+
+        if (sscanf(buf, "%hu", &value) != 1 ||
+            (value != 0 && value != 1 )) {
+                dprintk(KERN_ERR "no_pan_display_store : Invalid value\n");
+                return -EINVAL;
+        }
+
+        if(value == 0)
+                gNoPanDisplay = 0;
+        else if(value == 1)
+                gNoPanDisplay = 1;
+
+        return count;
+}
+
+static ssize_t phys_addr_show(struct device *device,
+                             struct device_attribute *attr, char *buf)
+{
+	struct fb_info *info = dev_get_drvdata(device);
+    return sprintf(buf, "%hu\n", info->fix.smem_start);
+}
+
+static ssize_t virt_addr_show(struct device *device,
+                             struct device_attribute *attr, char *buf)
+{
+	struct fb_info *info = dev_get_drvdata(device);
+	return sprintf(buf, "%hu\n", info->screen_base);
+}
+
+static struct device_attribute device_attrs[] = {
+    __ATTR(virt_addr, S_IRUGO | S_IWUGO, virt_addr_show, NULL),		
+    __ATTR(phys_addr, S_IRUGO | S_IWUGO, phys_addr_show, NULL),	
+    __ATTR(no_pan_display, S_IRUGO | S_IWUGO, no_pan_display_show, no_pan_display_store),
+    __ATTR(lcd_enable, S_IRUGO | S_IWUGO, show_lcd_enable, store_lcd_enable),
+    __ATTR(pixel_clock, S_IRUGO, show_pix_clk, NULL),
+//    __ATTR(osd_enable, S_IRUGO, show_osd_enable, store_osd_enable), 
+//    __ATTR(cursor_enable, S_IRUGO, show_cursor_enable, store_cursor_enable), 
+#ifdef CONFIG_HDMI_CAT6613
+    __ATTR(hdmi_status, S_IRUGO, show_hdmi_status, NULL),
+    __ATTR(hdmi_enable, S_IRUGO | S_IWUGO, show_hdmi_enable, store_hdmi_enable),
+#endif
+#ifdef CONFIG_VGA_EDID
+    __ATTR(vga_status, S_IRUGO, show_vga_status, NULL),
+    __ATTR(vga_detect, S_IRUGO | S_IWUGO, show_vga_edid, NULL),
+#endif
+};
+
+static int astfb_probe(struct platform_device *pdev)
+{
+	struct astfb_device	*astfbdev = NULL;
+	struct astfb_info *sfb;
+	struct fb_info *info;
+	struct device *dev = &pdev->dev;
+	int ret,i,retval;
+	char *mode_option;
+
+	dprintk("astfb_probe \n");
+
+	info = framebuffer_alloc(sizeof(struct astfb_info), dev);
+	if (!info) {
+			dev_err(dev, "cannot allocate memory\n");
+			return -ENOMEM;
+	}
+
+	sfb = info->par;
+	sfb->info = info;
+	sfb->pdev = pdev;	
+	sfb->fb_plat_data = (struct ast_fb_plat_data *)dev->platform_data;
+	strcpy(info->fix.id, sfb->pdev->name);
+
+	sfb->reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (!sfb->reg_res) {
+				dev_err(dev, "register resources unusable\n");
+		ret = -ENXIO;
+		goto free_info;
+	}
+
+	sfb->irq = platform_get_irq(pdev, 0);
+		if (!sfb->irq) {
+				dev_err(dev, "unable to get irq\n");
+		ret = -ENXIO;
+		goto free_info;
+	}
+
+	if(!sfb->fb_plat_data) {
+		dev_err(dev, "unable to get ast fb platform data\n");
+		ret = -ENXIO;
+		goto free_info;
+	}
+
+	info->fix.mmio_start	= sfb->reg_res->start;
+	info->fix.mmio_len		= sfb->reg_res->end - sfb->reg_res->start + 1;
+
+	if (!request_mem_region(info->fix.mmio_start, info->fix.mmio_len, pdev->name)) {
+			dev_err(dev, "cannot request CRT registers\n");
+			ret = -EBUSY;
+			goto free_info;
+	}
+
+	sfb->base = ioremap(info->fix.mmio_start, info->fix.mmio_len);
+	if (!sfb->base) {
+		dev_err(dev, "cannot map LCDC registers\n");
+		ret = -ENOMEM;
+		goto free_res;
+	}
+
+	info->fbops = &astfb_ops;
+
+	if(astfb_setup(sfb)) {
+		dev_warn(dev, "cannot get fb boot options will use default !!!\n");
+	}
+//	if (!mode_option) {
+		mode_option = "640x480-32@60";	 	
+		info->fix.smem_start = 0x47000000;
+
+//	}
+
+    if(fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8) != 1) {
+		dev_err(dev, "cannot find db modes \n");
+		ret = -ENOMEM;
+		goto free_res;
+    }
+
+
+	/* resource allocation */
+	info->fix.smem_len = SZ_2M * ((info->var.bits_per_pixel)/8 * NUMBER_OF_BUFFERS); //assign 16M for 1920*1080*32it double-buffering
+
+	printk("info->fix.smem_start = %x , len = %d , bpp = %d\n",info->fix.smem_start, info->fix.smem_len, info->var.bits_per_pixel);
+	
+	if (!request_mem_region(info->fix.smem_start, info->fix.smem_len, pdev->name)) {
+		dev_err(dev, "cannot request CRT mem\n");
+		ret = -EBUSY;
+		goto free_io;
+	}
+
+	info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
+	if (!info->screen_base) {
+		dev_err(dev, "cannot map CRT mem\n");
+		ret = -ENOMEM;
+		goto free_addr;
+	}
+
+	printk(KERN_INFO "FB Phys:%x, Virtual:%x \n", info->fix.smem_start, info->screen_base);
+
+    info->fix.type          = FB_TYPE_PACKED_PIXELS;
+    info->fix.type_aux      = 0;
+
+#if (NUMBER_OF_BUFFERS > 1)
+    info->fix.ypanstep = 1;
+#else
+    info->fix.ypanstep = 0;
+#endif
+
+	info->fix.xpanstep		= 0;
+	info->fix.ywrapstep 	= 0;
+	info->fix.visual 		= FB_VISUAL_TRUECOLOR,
+	info->fix.accel 		= FB_ACCEL_NONE;
+	info->flags 			= FBINFO_FLAG_DEFAULT;
+	info->pseudo_palette	= sfb->pseudo_palette;
+
+	/*
+	 * Allocate colourmap.
+	 */
+	ret=fb_alloc_cmap(&(info->cmap), 256, 0);
+	if(ret) {
+			dev_err(dev, "Alloc color map failed\n");
+			goto free_mem;
+	}
+
+	ret = request_irq(sfb->irq, astfb_isr, IRQF_SHARED, pdev->name, sfb);
+	if (ret) {
+			dev_err(dev, "Can't request LCD irq");
+			ret = -EBUSY;
+			goto free_cmap;
+	}
+	init_waitqueue_head(&wq);
+	
+	ret = astfb_check_var(&info->var, info);
+	if (ret)
+		goto free_irq;
+
+	init_timer(&sfb->timer);
+	sfb->timer.data = (long) sfb;
+	sfb->timer.function = sfb_timer;
+	astfb_set_par(info);
+	platform_set_drvdata(pdev, sfb);
+	ret = register_framebuffer(info);
+	if (!ret) {
+		for(i=0;i<sizeof(device_attrs)/sizeof(struct device_attribute);i++)
+				device_create_file(info->dev, &device_attrs[i]);
+		return 0;
+	}
+
+    dev_err(dev, "Failed to register framebuffer device: %d\n", ret);
+
+	astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) & ~CRT_CTRL_GRAPHIC_EN, AST_CRT_CTRL1);
+    platform_set_drvdata(pdev, NULL);
+free_irq:
+    free_irq(sfb->irq,sfb);
+free_cmap:
+    fb_dealloc_cmap(&info->cmap);
+free_mem:
+    ast_fbmem_free(sfb);
+free_addr:
+    if(sfb->addr_assign)
+            release_mem_region(info->fix.smem_start, info->fix.smem_len);
+free_io:
+    iounmap(sfb->base);
+free_res:
+    release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
+free_info:
+    framebuffer_release(info);
+    return ret;
+		
+}
+
+static int
+astfb_remove(struct platform_device *pdev)
+{
+	struct astfb_info *sfb = platform_get_drvdata(pdev);
+
+	unregister_framebuffer(sfb->info);
+	astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) & ~CRT_CTRL_GRAPHIC_EN, AST_CRT_CTRL1);
+	free_irq(sfb->irq,sfb);
+	fb_dealloc_cmap(&sfb->info->cmap);
+	iounmap(sfb->info->screen_base);
+	if(sfb->addr_assign)
+		release_mem_region(sfb->info->fix.smem_start, sfb->info->fix.smem_len);
+	iounmap(sfb->base);
+	release_mem_region(sfb->info->fix.mmio_start, sfb->info->fix.mmio_len);
+	framebuffer_release(sfb->info);
+	platform_set_drvdata(pdev, NULL);
+	dprintk("astfb_remove \n");
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int astfb_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	/* TODO */
+	return 0;
+}
+
+static int astfb_resume(struct platform_device *pdev)
+{
+	/* TODO */
+	return 0;
+}
+#else
+#define astfb_suspend NULL
+#define astfb_resume  NULL
+#endif
+
+/* driver ops */
+static struct platform_driver astfb_driver = {
+    .probe      = astfb_probe,
+    .remove     = astfb_remove,
+    .suspend    = astfb_suspend,
+    .resume     = astfb_resume,
+    .driver     = {
+        .name   = "ast-fb",
+        .owner  = THIS_MODULE,
+    },
+	
+};
+int __devinit astfb_init(void)
+{
+    return platform_driver_register(&astfb_driver);
+}
+
+static void __exit astfb_cleanup(void)
+{
+	printk(KERN_DEBUG "astfb: astfb_remove_module is called \n");
+
+	platform_driver_unregister(&astfb_driver);
+}
+
+module_init(astfb_init);
+module_exit(astfb_cleanup);
+
+MODULE_AUTHOR("Ryan Chen");
+MODULE_DESCRIPTION("Framebuffer driver for the ASPEED");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/hdmi_cat6613.c b/drivers/video/hdmi_cat6613.c
new file mode 100755
index 0000000..2a6d21f
--- /dev/null
+++ b/drivers/video/hdmi_cat6613.c
@@ -0,0 +1,545 @@
+/********************************************************************************
+* File Name     : drivers/video/hdmi_cat6613.c
+* Author        : Ryan Chen 
+* Description   : HDMI CAT6613 driver
+*
+* Copyright (C) 2012-2020  ASPEED Technology 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
+
+* History      :
+*    1. 2012/08/24 Ryan Chen create this file
+*
+********************************************************************************/
+
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+
+#include <mach/regs-cat6613.h>
+#include "edid.h"
+
+#define DEVICE_NAME "cat6613"
+#define CAT6613_DEVICE_ID   0xCA13
+
+struct cat6613_info {
+	struct i2c_client *client;
+	struct fb_info *fb_info;
+	struct aspeed_monitor_info *mon_info;
+	struct work_struct cat6613_work;
+	int state;//0:unplug 1:plug
+	int irq;
+};
+
+static struct cat6613_info cat6613_device;
+struct aspeed_monitor_info monitor_info;
+
+
+static void get_detailed_timing(unsigned char *block,
+				struct fb_videomode *mode)
+{
+	mode->xres = H_ACTIVE;
+	mode->yres = V_ACTIVE;
+	mode->pixclock = PIXEL_CLOCK;
+	mode->pixclock /= 1000;
+	mode->pixclock = KHZ2PICOS(mode->pixclock);
+	mode->right_margin = H_SYNC_OFFSET;
+	mode->left_margin = (H_ACTIVE + H_BLANKING) -
+		(H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
+	mode->upper_margin = V_BLANKING - V_SYNC_OFFSET -
+		V_SYNC_WIDTH;
+	mode->lower_margin = V_SYNC_OFFSET;
+	mode->hsync_len = H_SYNC_WIDTH;
+	mode->vsync_len = V_SYNC_WIDTH;
+	if (HSYNC_POSITIVE)
+		mode->sync |= FB_SYNC_HOR_HIGH_ACT;
+	if (VSYNC_POSITIVE)
+		mode->sync |= FB_SYNC_VERT_HIGH_ACT;
+	mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
+				     (V_ACTIVE + V_BLANKING));
+	if (INTERLACED) {
+		mode->yres *= 2;
+		mode->upper_margin *= 2;
+		mode->lower_margin *= 2;
+		mode->vsync_len *= 2;
+		mode->vmode |= FB_VMODE_INTERLACED;
+	}
+	else
+		mode->vmode=0;
+	mode->flag = FB_MODE_IS_DETAILED;
+
+}
+
+static void cat6613_parse_cea(void)
+{
+	int timing_offset,cea_data_offset=0,data_tag,data_len,vic,i;
+	char *ext=&cat6613_device.mon_info->edid[128];
+	struct fb_monspecs *specs=&cat6613_device.mon_info->specs;
+	
+	if(cat6613_device.mon_info->edid[126]==0 || ext[0]!=0x2) {
+			printk("DVI mode\n");
+			cat6613_device.mon_info->type=0; //dvi mode
+			return;
+	}
+  
+  printk("CEA Revision=%d\n", ext[1]);
+  
+  if(ext[3]& (1<<6)) {
+  	printk("HDMI mode\n");
+  	cat6613_device.mon_info->type=1; //hdmi mode
+  }
+  else {
+		printk("HDMI mode without audio\n");
+  	cat6613_device.mon_info->type=0; //dvi mode
+	}
+  
+  if(ext[2]==0) //no timing & cea data for parsing
+  	return;
+  
+  timing_offset=ext[2];
+  
+  //parsing cea data
+  if(timing_offset!=4) {
+  		while((cea_data_offset+4)!=timing_offset) {
+  			data_tag=(ext[cea_data_offset+4]>>5)&0x7; //bit 5~7
+  			data_len=ext[cea_data_offset+4]&0x1f; //bit 0~4
+  			switch(data_tag) {
+  				case 1:
+  					//printk("audio data block\n");
+  					break;
+  				case 2:
+  					//printk("video data block\n");
+  					for(i=1;i<=data_len;i++) {
+  						vic=ext[cea_data_offset+4+i]&0x7f;
+  						//add 720p60 timing
+  						if(vic==4) {
+  							//printk("add 1280x720p60 timing\n");
+  							memcpy(&specs->modedb[specs->modedb_len], &(panels[8].mode),sizeof(struct fb_videomode));
+  							specs->modedb_len++;
+  						}
+  						//add 1080p60 timing
+  						if(vic==16) {
+  							//printk("add 1920x1080p60 timing\n");
+  							memcpy(&specs->modedb[specs->modedb_len], &(panels[9].mode),sizeof(struct fb_videomode));
+  							specs->modedb_len++;
+  						}
+  						if(vic==2 || vic==3) {
+  							//printk("add 720x480p60 timing\n");
+  							memcpy(&specs->modedb[specs->modedb_len], &(panels[10].mode),sizeof(struct fb_videomode));
+  							specs->modedb_len++;
+  						}
+  						
+  					}
+  					break;
+  				case 3:
+  					//printk("vendor data block\n");
+  					break;
+  				case 4:
+  					//printk("speaker data block\n");
+  					break;
+  				default:
+  					//printk("unknown data block tag=%d\n",data_tag);
+  					break;
+  			}
+  			cea_data_offset+=(data_len+1); //go to next block
+  		}
+	}
+  while(ext[timing_offset]!=0) {
+  	//printk("%x\n",ext[timing_offset+17]);
+		get_detailed_timing(&ext[timing_offset], &specs->modedb[specs->modedb_len]);
+		specs->modedb_len++;
+		timing_offset+=18;
+	}
+	
+}
+
+static int cat6613_reset(struct i2c_client *client)
+{
+	int rc;
+	rc = i2c_smbus_write_byte_data(client, REG_TX_BANK_CTRL, 0x00);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_SW_RST, 0x3d);
+	msleep(2);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_SW_RST, 0x1d);
+	msleep(2);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_HDMI_MODE, 0x00);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AV_MUTE, 0x01);
+	
+	//set int
+	rc |=i2c_smbus_write_byte_data(client,REG_TX_INT_CTRL, 0x40);
+	rc |=i2c_smbus_write_byte_data(client,REG_TX_INT_MASK1, 0xfd);
+	rc |=i2c_smbus_write_byte_data(client,REG_TX_INT_MASK2, 0xff) ;
+	rc |=i2c_smbus_write_byte_data(client,REG_TX_INT_MASK3, 0x7f);
+
+	return rc;
+
+}
+
+static int cat6613_afe(struct i2c_client *client)
+{
+	int tmds,rc=0;
+	if(cat6613_device.fb_info) {
+		tmds=1000000/(cat6613_device.fb_info->var.pixclock);
+		if(tmds > 80) {
+			rc = i2c_smbus_write_byte_data(client, REG_TX_AFE_DRV_CTRL,0x10);
+			rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_XP_CTRL,0x88);
+			rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_ISW_CTRL,0x10);
+			rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_IP_CTRL,0x84);
+			
+		}
+		else {
+
+			rc = i2c_smbus_write_byte_data(client, REG_TX_AFE_DRV_CTRL,0x10);
+			rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_XP_CTRL,0x18);
+			rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_ISW_CTRL,0x10);
+			rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_IP_CTRL,0x0c);
+		}
+		rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_DRV_CTRL,0x00);	
+	}	
+	
+	return rc;
+}
+
+static int cat6613_set_av(struct i2c_client *client)
+{
+	int rc=0;
+	
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_SW_RST,0xd); //reset av
+	msleep(1);
+	if(cat6613_device.mon_info->type==0) {
+		rc |= i2c_smbus_write_byte_data(client, REG_TX_HDMI_MODE,0);  //dvi mode
+		rc |= i2c_smbus_write_byte_data(client, REG_TX_SW_RST,5);
+		msleep(1);
+		return rc;
+	}
+	
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_BANK_CTRL,1);  //switch bank 1
+
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB1,0x12);  //set underscan
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB2,0x8);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB3,0x0);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB4,0x0);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB5,0x0);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB6,0x0);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB7,0x0);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB8,0x0);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB9,0x0);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB10,0x0);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB11,0x0);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB12,0x0);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB13,0x0);
+	
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_SUM,0x55);  //check sum
+		
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_BANK_CTRL,0);  //switch bank 0	
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_PKT_GENERAL_CTRL,1);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_NULL_CTRL,1);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_ACP_CTRL,0);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AVI_INFOFRM_CTRL,3);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AUD_INFOFRM_CTRL,1);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_MPG_INFOFRM_CTRL,0);
+
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_HDMI_MODE,1);  //hdmi mode
+	
+	rc |= i2c_smbus_write_byte_data(client, 0xf8,0xc3);  
+	rc |= i2c_smbus_write_byte_data(client, 0xf8,0xa5);
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_PKT_SINGLE_CTRL,0x0); //set auto cts
+
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AUDIO_CTRL0,0x0);  
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AUDIO_CTRL0,0x1);  //set i2s 16bit
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_AUDIO_CTRL1,0x1);  //set not full packet mode & 32bit i2s
+	
+	rc |= i2c_smbus_write_byte_data(client, REG_TX_SW_RST,1);
+	msleep(1);  
+	
+	return rc;
+	
+}
+
+static int cat6613_clear_mute(struct i2c_client *client)
+{
+	int rc;
+	rc = i2c_smbus_write_byte_data(client, REG_TX_AV_MUTE,0);
+	return rc;
+}
+
+
+static int cat6613_wait_ddc(struct i2c_client *client)
+{
+	int rc,count;
+	
+	for(count=0;count<10;count++) {
+		rc=i2c_smbus_read_byte_data(client,REG_TX_DDC_STATUS);
+		if(rc & B_DDC_DONE)
+			return 0;
+		msleep(1);
+	}
+	printk("ddc timeout\n");
+	i2c_smbus_write_byte_data(client,REG_TX_DDC_MASTER_CTRL, B_MASTERHOST ) ;
+	i2c_smbus_write_byte_data(client,REG_TX_DDC_CMD, CMD_DDC_ABORT) ;			
+	return -1;
+
+}
+
+static int cat6613_read_edid(struct i2c_client *client)
+{
+	int j ;
+	int remained_byte, offset, count;
+	remained_byte = 256 ;
+	offset=0;
+	
+	while(offset<256) {
+		count = (remained_byte<32)?remained_byte:32 ;
+		i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_DDC_MASTER_CTRL, B_MASTERDDC|B_MASTERHOST ) ;
+		i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_DDC_CMD, CMD_FIFO_CLR);
+		if(cat6613_wait_ddc(cat6613_device.client)) {
+			return -1;
+		}
+		
+		i2c_smbus_write_byte_data(client,REG_TX_DDC_HEADER, 0xA0) ;
+		i2c_smbus_write_byte_data(client,REG_TX_DDC_REQOFF, offset) ;
+		i2c_smbus_write_byte_data(client,REG_TX_DDC_REQCOUNT, count) ;
+		i2c_smbus_write_byte_data(client,REG_TX_DDC_EDIDSEG, 0) ;
+		i2c_smbus_write_byte_data(client,REG_TX_DDC_CMD, 3);
+		if(cat6613_wait_ddc(cat6613_device.client)) {
+			return -1;
+		}
+		for( j = 0 ; j < count ; j++)
+		{
+			cat6613_device.mon_info->edid[offset+j] = i2c_smbus_read_byte_data(client,REG_TX_DDC_READFIFO); ;
+		}
+		remained_byte -= count ;
+		offset += count ;
+	}
+	return 0;
+	
+}
+
+static void cat6613_add_modes(void)
+{
+	int i;
+	struct fb_monspecs *specs=&cat6613_device.mon_info->specs;
+	struct fb_info *info=cat6613_device.fb_info;
+	
+	for(i=0;i<specs->modedb_len;i++) {
+		fb_add_videomode(&specs->modedb[i],&info->modelist);
+	}
+	
+}
+
+static void cat6613_del_modes(void)
+{
+	int i;
+	struct fb_monspecs *specs=&cat6613_device.mon_info->specs;
+	struct fb_info *info=cat6613_device.fb_info;
+	if(!info)
+		return;
+	
+	for(i=0;i<specs->modedb_len;i++) {
+		fb_delete_videomode(&specs->modedb[i],&info->modelist);
+	}
+}
+
+static void cat6613_handle(struct work_struct *work)
+{
+	char int_status,sys_status,rc,int_status3;
+	struct fb_var_screeninfo tmp_var;
+	int_status=i2c_smbus_read_byte_data(cat6613_device.client,REG_TX_INT_STAT1);
+	sys_status=i2c_smbus_read_byte_data(cat6613_device.client, REG_TX_SYS_STATUS);
+	int_status3=i2c_smbus_read_byte_data(cat6613_device.client,REG_TX_INT_STAT3);
+	if(!(sys_status&B_INT_ACTIVE))
+		printk("cat6613_handle: no int\n");
+	else {
+#if 0
+		if(int_status & B_INT_DDCFIFO_ERR) {
+			printk("B_INT_DDCFIFO_ERR\n");
+			i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_DDC_MASTER_CTRL, B_MASTERHOST ) ;
+			i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_DDC_CMD, CMD_FIFO_CLR);
+		}
+		
+		if(int_status & B_INT_DDC_BUS_HANG) {
+			printk("B_INT_DDC_BUS_HANG\n");
+			i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_DDC_MASTER_CTRL, B_MASTERHOST ) ;
+			i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_DDC_CMD, CMD_DDC_ABORT) ;
+		}		
+		if(int_status & B_INT_HPD_PLUG) {
+			if(sys_status & B_HPDETECT)
+				printk("HPD PLUG\n");
+			else 
+				printk("HPD UN PLUG 0\n");
+			i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_INT_CLR0,B_CLR_HPD);
+		}
+		if(int_status3 & B_INT_VIDSTABLE) {
+			if(sys_status & B_TXVIDSTABLE) {
+				printk("VIDSTABLE\n");
+				i2c_smbus_write_byte_data(cat6613_device.client, REG_TX_AFE_DRV_CTRL,0x00);
+			}
+			else
+				printk("UN VIDSTABLE\n");
+			i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_INT_CLR1,B_CLR_VIDSTABLE);
+		}
+#endif		
+		if(int_status & B_INT_RX_SENSE) {
+			if(sys_status& B_RXSENDETECT) {
+				if(cat6613_device.state==0) {
+					rc=cat6613_read_edid(cat6613_device.client);
+					if(!rc) {
+						rc=fb_parse_edid(cat6613_device.mon_info->edid,&tmp_var);
+						if(!rc)
+							cat6613_device.state=1;
+					}
+				}
+			}
+			else {
+				printk("HPD UN PLUG 0\n");
+				if(cat6613_device.state==1) {
+					printk("HPD UN PLUG 1\n");
+					cat6613_del_modes();
+					cat6613_device.mon_info->status=0;
+					cat6613_device.state=0;
+				}
+			}
+			i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_INT_CLR0,B_CLR_RXSENSE);
+		}
+	}
+	
+	i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_SYS_STATUS, sys_status | B_INTACTDONE );
+	i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_SYS_STATUS, sys_status);
+	enable_irq(cat6613_device.irq);
+}
+
+static irqreturn_t cat6613_isr(int irq, void *parm)
+{
+	
+	disable_irq_nosync(cat6613_device.irq);
+	schedule_work(&cat6613_device.cat6613_work);
+	return IRQ_HANDLED;
+}
+
+static int hdmi_cat6613_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	int rc=0;
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
+		return -ENODEV;
+	
+	rc=(i2c_smbus_read_byte_data(client, REG_TX_VENDOR_ID1)<<8)&0xff00;
+	rc|=i2c_smbus_read_byte_data(client, REG_TX_DEVICE_ID0);
+	if(rc != CAT6613_DEVICE_ID) {
+		printk(KERN_ERR "%s: read id fail\n", __func__);
+		return -ENODEV;
+	}
+	
+	cat6613_device.client=client;
+	cat6613_device.irq=client->irq;
+	cat6613_device.mon_info=&monitor_info;
+	
+	//reset
+	rc=cat6613_reset(client);
+	if(rc)	
+		printk(KERN_ERR "%s: reset fail\n", __func__);
+	
+	INIT_WORK(&cat6613_device.cat6613_work, cat6613_handle);
+	rc = request_irq(cat6613_device.irq, cat6613_isr, IRQF_DISABLED, DEVICE_NAME, NULL);
+	if(rc) {
+		printk(KERN_ERR "%s: request irq fail\n", __func__);
+		return rc;
+	}	
+	
+	return rc;
+}
+
+static int __devexit hdmi_cat6613_remove(struct i2c_client *client)
+{
+
+	return 0;
+}
+
+
+static const struct i2c_device_id hmdi_cat6613_id[] = {
+	{ DEVICE_NAME, 0 },
+	{ }
+};
+
+static struct i2c_driver hdmi_cat6613_i2c_driver = {
+	.driver = {
+		.name = DEVICE_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = hdmi_cat6613_probe,
+	.remove =  __exit_p(hdmi_cat6613_remove),
+	.id_table = hmdi_cat6613_id,
+};
+
+
+int aspeed_hdmi_get_info(struct fb_info *fb_info) 
+{
+	
+	if(!fb_info) {
+		printk("no fb_info\n");
+		return -1;
+	}
+	cat6613_device.fb_info=fb_info;
+	
+	if(cat6613_device.state==0)
+		return 1;
+	
+	if(cat6613_device.mon_info->status==0) {
+		if(monitor_info.specs.modedb)
+			fb_destroy_modedb(monitor_info.specs.modedb);
+		fb_edid_to_monspecs(cat6613_device.mon_info->edid, &cat6613_device.mon_info->specs);
+		cat6613_parse_cea();
+		cat6613_add_modes();
+		cat6613_device.mon_info->status=1;	
+	}
+	return 0;	
+}
+
+void aspeed_hdmi_enable(int en)
+{
+	if(en==0) {
+		i2c_smbus_write_byte_data(cat6613_device.client, REG_TX_HDMI_MODE, 0x00);
+		i2c_smbus_write_byte_data(cat6613_device.client, REG_TX_AV_MUTE, 0x01);
+	}
+	else {
+		cat6613_set_av(cat6613_device.client);
+		cat6613_afe(cat6613_device.client);
+		cat6613_clear_mute(cat6613_device.client);
+	}
+}
+
+static int __init hdmi_cat6613_init(void)
+{
+	int ret;
+	
+	ret = i2c_add_driver(&hdmi_cat6613_i2c_driver);
+	if (ret)
+		printk(KERN_ERR "%s: failed to add i2c driver\n", __func__);
+
+	return ret;
+}
+
+static void __exit hdmi_cat6613_exit(void)
+{
+	i2c_del_driver(&hdmi_cat6613_i2c_driver);
+}
+
+module_init(hdmi_cat6613_init);
+module_exit(hdmi_cat6613_exit);
+
+EXPORT_SYMBOL(aspeed_hdmi_get_info);
+EXPORT_SYMBOL(aspeed_hdmi_enable);
+
+MODULE_AUTHOR("Ryan Chen <jsho@aspeed-tech.com>");
+MODULE_DESCRIPTION("CAT6023 HDMI Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 9d285f6..5702145 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -233,6 +233,12 @@ config ORION5X_WATCHDOG
 	  To compile this driver as a module, choose M here: the
 	  module will be called orion5x_wdt.
 
+config AST_WATCHDOG
+	tristate "ASPEED GUC watchdog"
+	depends on WATCHDOG 
+	help
+	  Watchdog timer for ASPEED chips.
+
 # ARM26 Architecture
 
 # AVR32 Architecture
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index e352bbb..ba47642 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
 obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o
 obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o
 obj-$(CONFIG_ORION5X_WATCHDOG) += orion5x_wdt.o
+obj-$(CONFIG_AST_WATCHDOG) += ast_wdt.o
 
 # ARM26 Architecture
 
diff --git a/drivers/watchdog/ast_wdt.c b/drivers/watchdog/ast_wdt.c
new file mode 100644
index 0000000..845f1db
--- /dev/null
+++ b/drivers/watchdog/ast_wdt.c
@@ -0,0 +1,519 @@
+/********************************************************************************
+* File Name     : ast_wdt
+* 
+* Copyright (C) 2012-2020  ASPEED Technology 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/fs.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/semaphore.h>
+#include <asm/uaccess.h>
+
+#include <linux/platform_device.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_COLDFIRE
+#include <asm/arch/irqs.h>
+#include <asm/arch/ast_wdt.h>
+#include <asm/arch/platform.h>
+#else
+#include <mach/irqs.h>
+#include <mach/ast_wdt.h>
+#include <mach/platform.h>
+#endif
+
+#define TICKS_PER_uSEC                  1 
+
+
+typedef unsigned char bool_T;
+
+#ifdef TRUE
+#undef TRUE
+#endif
+
+#ifdef FALSE
+#undef FALSE
+#endif
+
+#define TRUE	1
+#define FALSE	0
+
+#if defined(CONFIG_COLDFIRE)
+#define WDT_BASE_VA		AST_WDT_BASE
+
+#else
+#define WDT_BASE_VA		(IO_ADDRESS(AST_WDT_BASE))
+#endif
+
+#define WDT_CntSts              (WDT_BASE_VA+0x00)
+#define WDT_Reload              (WDT_BASE_VA+0x04)
+#define WDT_Restart             (WDT_BASE_VA+0x08)
+#define WDT_Ctrl                (WDT_BASE_VA+0x0C)
+#define WDT_TimeOut             (WDT_BASE_VA+0x10)
+#define WDT_Clr                 (WDT_BASE_VA+0x14)
+#define WDT_RstWd               (WDT_BASE_VA+0x18)
+
+
+#define AST_READ_REG(r)		(*((volatile unsigned int *) (r)))
+#define AST_WRITE_REG(r,v)		(*((volatile unsigned int *) (r)) = ((unsigned int)   (v)))
+
+
+#define WDT_CLK_SRC_EXT		0
+#define WDT_CLK_SRC_PCLK	1
+
+//Global Variables
+#define WD_TIMO 6			/* Default heartbeat = 6 seconds */
+
+static int heartbeat = WD_TIMO;
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+static unsigned long wdt_is_open;
+static char expect_close;
+
+//Function Declaration
+int __init wdt_init(void);
+
+static irqreturn_t wdt_isr(int irq, void *devid, struct pt_regs *regs)
+{
+	/* clear timeout */
+	AST_WRITE_REG(WDT_Clr, 1);
+
+	return (IRQ_HANDLED);
+}
+
+void wdt_disable(void)
+{
+    register unsigned int regVal;
+                                                                                     
+    /* reset WDT_Ctrl[0] as 0 */
+    regVal = AST_READ_REG(WDT_Ctrl);
+    regVal &= 0xFFFFFFFE;
+    AST_WRITE_REG(WDT_Ctrl, regVal);
+}
+
+void wdt_sel_clk_src(unsigned char sourceClk)
+{
+    register unsigned int regVal;
+                                                                                     
+    regVal = AST_READ_REG(WDT_Ctrl);
+    if (sourceClk == WDT_CLK_SRC_PCLK)
+    {
+        /* reset WDT_Ctrl[4] as 0 */
+        regVal &= 0xFFFFFFEF;
+    }
+    else
+    {
+        /* set WDT_Ctrl[4] as 1 */
+        regVal |= 0x00000010;
+    }
+    AST_WRITE_REG(WDT_Ctrl, regVal);
+}
+
+void wdt_set_timeout_action(bool_T bResetOut, bool_T bIntrSys, bool_T bResetSys)
+{
+	register unsigned int regVal;
+
+	regVal = AST_READ_REG(WDT_Ctrl);
+
+	if (bResetOut)
+	{
+		/* set WDT_Ctrl[3] = 1 */
+		regVal |= 0x00000008;
+	}
+	else
+	{
+		/* reset WDT_Ctrl[3] = 0 */
+		regVal &= 0xFFFFFFF7;
+	}
+
+	if (bIntrSys)
+	{
+		/* set WDT_Ctrl[2] = 1 */
+		regVal |= 0x00000004;
+	}
+	else
+	{
+		/* reset WDT_Ctrl[2] = 0 */
+		regVal &= 0xFFFFFFFB;
+	}
+
+	if (bResetSys)
+	{
+		/* set WDT_Ctrl[1] = 1 */
+		regVal |= 0x00000002;
+	}
+	else
+	{
+		/* reset WDT_Ctrl[1] = 0 */
+		regVal &= 0xFFFFFFFD;
+	}
+
+	AST_WRITE_REG(WDT_Ctrl, regVal);
+}
+
+void wdt_enable(void)
+{
+	register unsigned int regVal;
+
+	/* set WDT_Ctrl[0] as 1 */
+	regVal = AST_READ_REG(WDT_Ctrl);
+	regVal |= 1;
+	AST_WRITE_REG(WDT_Ctrl, regVal);
+}
+
+void wdt_restart_new(unsigned int nPeriod, int sourceClk, bool_T bResetOut, bool_T bIntrSys, bool_T bResetSys, bool_T bUpdated)
+{
+	wdt_disable();
+
+	AST_WRITE_REG(WDT_Reload, nPeriod);
+
+	wdt_sel_clk_src(sourceClk);
+
+	wdt_set_timeout_action(bResetOut, bIntrSys, bResetSys);
+
+	AST_WRITE_REG(WDT_Restart, 0x4755);	/* reload! */
+
+	if (!bUpdated)
+  	  wdt_enable();
+}
+
+void wdt_restart(void)
+{
+	wdt_disable();
+	AST_WRITE_REG(WDT_Restart, 0x4755);	/* reload! */
+	wdt_enable();
+}
+
+
+/**
+ *	wdt_set_heartbeat:
+ *	@t:		the new heartbeat value that needs to be set.
+ *
+ *	Set a new heartbeat value for the watchdog device. If the heartbeat value is
+ *	incorrect we keep the old value and return -EINVAL. If successfull we
+ *	return 0.
+ */
+static int wdt_set_heartbeat(int t)
+{
+  if ((t < 1) || (t > 1000))
+      return -EINVAL;
+      
+  heartbeat=t;
+      
+  wdt_restart_new(TICKS_PER_uSEC*1000000*t, WDT_CLK_SRC_EXT, FALSE, TRUE, FALSE, FALSE);
+  return 0;
+}
+
+/*
+   Kernel Interfaces
+*/
+
+/**
+ *	ast_wdt_write: 
+ *	@file: file handle to the watchdog
+ *	@buf: buffer to write (unused as data does not matter here
+ *	@count: count of bytes
+ *	@ppos: pointer to the position to write. No seeks allowed
+ *
+ *	A write to a watchdog device is defined as a keepalive signal. Any
+ *	write of data will do, as we we don't define content meaning.
+ */
+         
+ static ssize_t ast_wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+ {
+   if(count) 
+   {
+     if (!nowayout)
+     {
+        size_t i;
+             
+        /* In case it was set long ago */
+        expect_close = 0;
+                         
+        for (i = 0; i != count; i++) 
+        {
+          char c;
+          if (get_user(c, buf + i))
+            return -EFAULT;
+          if (c == 'V')
+            expect_close = 42;
+        }
+      }
+      wdt_restart();
+   }
+   return count; 
+ }
+ 
+/**
+ *	ast_wdt_ioctl:
+ *	@inode: inode of the device
+ *	@file: file handle to the device
+ *	@cmd: watchdog command
+ *	@arg: argument pointer
+ * *	The watchdog API defines a common set of functions for all watchdogs
+ *	according to their available features. We only actually usefully support
+ *	querying capabilities and current status.
+ */
+          
+static int ast_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+  void __user *argp = (void __user *)arg;
+  int __user *p = argp;
+  int new_heartbeat;
+      
+  static struct watchdog_info ident = 
+  {
+    .options 		= WDIOF_SETTIMEOUT|
+                          WDIOF_MAGICCLOSE|
+                          WDIOF_KEEPALIVEPING,
+    .firmware_version 	= 1,
+    .identity 		= "AST WDT",
+  };
+  
+  switch(cmd)
+  {
+    default:
+      return -ENOIOCTLCMD;
+    case WDIOC_GETSUPPORT:
+      return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;                      
+    case WDIOC_GETSTATUS:
+    case WDIOC_GETBOOTSTATUS:
+      return put_user(0, p);
+    case WDIOC_KEEPALIVE:
+      wdt_restart();
+      return 0;
+    case WDIOC_SETTIMEOUT:
+      if (get_user(new_heartbeat, p))
+        return -EFAULT;
+
+      if (wdt_set_heartbeat(new_heartbeat))
+        return -EINVAL;
+
+      /* Fall */
+    case WDIOC_GETTIMEOUT:
+      return put_user(heartbeat, p);      
+  }
+}
+/**
+*	ast_wdt_open:
+*	@inode: inode of device
+*	@file: file handle to device
+*
+*	The watchdog device has been opened. The watchdog device is single
+*	open and on opening we load the counters. Counter zero is a 100Hz
+*	cascade, into counter 1 which downcounts to reboot. When the counter
+*	triggers counter 2 downcounts the length of the reset pulse which
+*	set set to be as long as possible.
+*/
+          
+static int ast_wdt_open(struct inode *inode, struct file *file)
+{
+  if(test_and_set_bit(0, &wdt_is_open))
+      return -EBUSY;
+  /*
+   *	Activate
+   */
+ // wdt_init(); 
+  wdt_restart();
+  return nonseekable_open(inode, file);
+} 
+
+/**
+*	ast_wdt_release:
+*	@inode: inode to board
+*	@file: file handle to board
+*
+*	The watchdog has a configurable API. There is a religious dispute
+*	between people who want their watchdog to be able to shut down and
+*	those who want to be sure if the watchdog manager dies the machine
+*	reboots. In the former case we disable the counters, in the latter
+*	case you have to open it again very soon.
+*/
+          
+static int ast_wdt_release(struct inode *inode, struct file *file)
+{
+  if (expect_close == 42 || !nowayout) 
+  {
+      wdt_disable();
+      clear_bit(0, &wdt_is_open);
+  } 
+  else 
+  {
+      printk(KERN_CRIT "wdt: WDT device closed unexpectedly.  WDT will not stop!\n");
+      wdt_restart();
+  }
+  expect_close = 0;
+  return 0;
+}
+
+/**
+*	notify_sys:
+*	@this: our notifier block
+*	@code: the event being reported
+*	@unused: unused
+*
+*	Our notifier is called on system shutdowns. We want to turn the card
+*	off at reboot otherwise the machine will reboot again during memory
+*	test or worse yet during the following fsck. This would suck, in fact
+*	trust me - if it happens it does suck.
+*/
+          
+static int ast_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
+{
+   if(code==SYS_DOWN || code==SYS_HALT) 
+   {
+     /* Turn the WDT off */
+     wdt_disable();
+   }
+   return NOTIFY_DONE;
+}
+
+extern void ast_soc_wdt_reset(void)
+{
+	writel(0x10 , WDT_BASE_VA+0x04);
+	writel(0x4755, WDT_BASE_VA+0x08);
+	writel(0x3, WDT_BASE_VA+0x0c);
+}
+
+EXPORT_SYMBOL(ast_soc_wdt_reset);
+
+static struct file_operations ast_wdt_fops = 
+{
+  .owner	= THIS_MODULE,
+  .llseek	= no_llseek,
+  .write	= ast_wdt_write,
+  .ioctl	= ast_wdt_ioctl,
+  .open		= ast_wdt_open,
+  .release	= ast_wdt_release,
+};
+
+static struct miscdevice ast_wdt_miscdev = 
+{
+   .minor	= WATCHDOG_MINOR,
+   .name	= "watchdog",
+   .fops	= &ast_wdt_fops,
+};
+     
+static struct notifier_block ast_wdt_notifier = 
+{
+   .notifier_call=ast_wdt_notify_sys,
+};
+
+static int ast_wdt_probe(struct platform_device *pdev)
+{
+   int ret;  
+    
+   wdt_disable();
+   wdt_sel_clk_src(WDT_CLK_SRC_EXT);
+   wdt_set_timeout_action(FALSE, FALSE, FALSE);
+	
+   /* register ISR */
+   if (request_irq(IRQ_WDT, (void *)wdt_isr, IRQF_DISABLED, "WDT", NULL))
+   {
+     printk("unable to register interrupt INT_WDT = %d\n", IRQ_WDT);
+     return (-1);
+   }
+   else
+     printk("success to register interrupt for INT_WDT (%d)\n", IRQ_WDT);
+
+   ret = register_reboot_notifier(&ast_wdt_notifier);
+   if(ret) 
+   {
+     printk(KERN_ERR "wdt: cannot register reboot notifier (err=%d)\n", ret);
+     free_irq(IRQ_WDT, NULL);
+     return ret;
+   }
+
+   ret = misc_register(&ast_wdt_miscdev);
+   if (ret) 
+   {
+      printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n",WATCHDOG_MINOR, ret);
+      unregister_reboot_notifier(&ast_wdt_notifier);   
+      return ret;
+   }
+
+   /* interrupt the system while WDT timeout */
+   wdt_restart_new(TICKS_PER_uSEC*1000000*heartbeat, WDT_CLK_SRC_EXT, FALSE, TRUE, FALSE, TRUE);
+   
+   printk(KERN_INFO "AST WDT is installed.(irq = %d, heartbeat = %d secs, nowayout = %d)\n",IRQ_WDT,heartbeat,nowayout);
+
+   return (0);
+}
+
+static int ast_wdt_remove(struct platform_device *dev)
+{
+	misc_deregister(&ast_wdt_miscdev);
+	disable_irq(IRQ_WDT);
+	free_irq(IRQ_WDT, NULL);		
+	return 0;
+}
+
+static void ast_wdt_shutdown(struct platform_device *dev)
+{
+	wdt_disable();
+}
+
+static struct platform_driver ast_wdt_driver = {
+        .probe          = ast_wdt_probe,
+        .remove         = ast_wdt_remove,
+        .shutdown       = ast_wdt_shutdown,
+#if 0        
+        .suspend                = ast_wdt_suspend,
+        .resume         = ast_wdt_resume,
+#endif        
+        .driver         = {
+                .owner  = THIS_MODULE,
+                .name   = "ast-wdt",
+        },
+};
+
+static char banner[] __initdata = KERN_INFO "ASPEED Watchdog Timer, ASPEED Technology Inc.\n";
+
+static int __init watchdog_init(void)
+{
+        printk(banner);
+
+        return platform_driver_register(&ast_wdt_driver);
+}
+
+static void __exit watchdog_exit(void)
+{
+        platform_driver_unregister(&ast_wdt_driver);
+}
+
+module_init(watchdog_init);
+module_exit(watchdog_exit);
+
+MODULE_DESCRIPTION("Driver for AST Watch Dog");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_LICENSE("GPL");
diff --git a/fs/Kconfig b/fs/Kconfig
index 522469a..382fa76 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -907,6 +907,10 @@ config EFS_FS
 	  To compile the EFS file system support as a module, choose M here: the
 	  module will be called efs.
 
+
+# Patched by YAFFS
+#source "fs/yaffs2/Kconfig"
+
 source "fs/jffs2/Kconfig"
 # UBIFS File system configuration
 source "fs/ubifs/Kconfig"
diff --git a/fs/Makefile b/fs/Makefile
index d9f8afe..cbb1738 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -122,3 +122,6 @@ obj-$(CONFIG_HPPFS)		+= hppfs/
 obj-$(CONFIG_DEBUG_FS)		+= debugfs/
 obj-$(CONFIG_OCFS2_FS)		+= ocfs2/
 obj-$(CONFIG_GFS2_FS)           += gfs2/
+
+# Patched by YAFFS
+#obj-$(CONFIG_YAFFS_FS)		+= yaffs2/
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 403aa50..b0068f7 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -24,12 +24,14 @@ struct mmc_cid {
 };
 
 struct mmc_csd {
+	unsigned char		structure;
 	unsigned char		mmca_vsn;
 	unsigned short		cmdclass;
 	unsigned short		tacc_clks;
 	unsigned int		tacc_ns;
 	unsigned int		r2w_factor;
 	unsigned int		max_dtr;
+	unsigned int		erase_size;		/* In sectors */
 	unsigned int		read_blkbits;
 	unsigned int		write_blkbits;
 	unsigned int		capacity;
@@ -40,8 +42,17 @@ struct mmc_csd {
 };
 
 struct mmc_ext_csd {
+	u8			rev;
+	u8			erase_group_def;
+	u8			sec_feature_support;
+	unsigned int		sa_timeout;		/* Units: 100ns */
 	unsigned int		hs_max_dtr;
 	unsigned int		sectors;
+	unsigned int		hc_erase_size;		/* In sectors */
+	unsigned int		hc_erase_timeout;	/* In milliseconds */
+	unsigned int		sec_trim_mult;	/* Secure trim multiplier  */
+	unsigned int		sec_erase_mult;	/* Secure erase multiplier */
+	unsigned int		trim_timeout;		/* In milliseconds */
 };
 
 struct sd_scr {
@@ -89,12 +100,18 @@ struct mmc_card {
 #define MMC_TYPE_MMC		0		/* MMC card */
 #define MMC_TYPE_SD		1		/* SD card */
 #define MMC_TYPE_SDIO		2		/* SDIO card */
+#define MMC_TYPE_SD_COMBO	3		/* SD combo (IO+mem) card */
 	unsigned int		state;		/* (our) card state */
 #define MMC_STATE_PRESENT	(1<<0)		/* present in sysfs */
 #define MMC_STATE_READONLY	(1<<1)		/* card is read-only */
 #define MMC_STATE_HIGHSPEED	(1<<2)		/* card is in high speed mode */
 #define MMC_STATE_BLOCKADDR	(1<<3)		/* card uses block-addressing */
 
+	unsigned int		erase_size;	/* erase size in sectors */
+ 	unsigned int		erase_shift;	/* if erase unit is power 2 */
+ 	unsigned int		pref_erase;	/* in sectors */
+ 	u8			erased_byte;	/* value of erased bytes */
+
 	u32			raw_cid[4];	/* raw card CID */
 	u32			raw_csd[4];	/* raw card CSD */
 	u32			raw_scr[2];	/* raw card SCR */
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 14b81f3..dd11ae5 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -31,6 +31,7 @@
 #define MMC_ALL_SEND_CID          2   /* bcr                     R2  */
 #define MMC_SET_RELATIVE_ADDR     3   /* ac   [31:16] RCA        R1  */
 #define MMC_SET_DSR               4   /* bc   [31:16] RCA            */
+#define MMC_SLEEP_AWAKE		  5   /* ac   [31:16] RCA 15:flg R1b */
 #define MMC_SWITCH                6   /* ac   [31:0] See below   R1b */
 #define MMC_SELECT_CARD           7   /* ac   [31:16] RCA        R1  */
 #define MMC_SEND_EXT_CSD          8   /* adtc                    R1  */
@@ -127,6 +128,7 @@
 #define R1_STATUS(x)            (x & 0xFFFFE000)
 #define R1_CURRENT_STATE(x)	((x & 0x00001E00) >> 9)	/* sx, b (4 bits) */
 #define R1_READY_FOR_DATA	(1 << 8)	/* sx, a */
+#define R1_SWITCH_ERROR		(1 << 7)	/* sx, c */
 #define R1_APP_CMD		(1 << 5)	/* sr, c */
 
 /*
@@ -249,11 +251,21 @@ struct _mmc_csd {
  * EXT_CSD fields
  */
 
-#define EXT_CSD_BUS_WIDTH	183	/* R/W */
-#define EXT_CSD_HS_TIMING	185	/* R/W */
-#define EXT_CSD_CARD_TYPE	196	/* RO */
-#define EXT_CSD_REV		192	/* RO */
-#define EXT_CSD_SEC_CNT		212	/* RO, 4 bytes */
+#define EXT_CSD_ERASE_GROUP_DEF		175	/* R/W */
+#define EXT_CSD_ERASED_MEM_CONT		181	/* RO */
+#define EXT_CSD_BUS_WIDTH		183	/* R/W */
+#define EXT_CSD_HS_TIMING		185	/* R/W */
+#define EXT_CSD_REV			192	/* RO */
+#define EXT_CSD_STRUCTURE		194	/* RO */
+#define EXT_CSD_CARD_TYPE		196	/* RO */
+#define EXT_CSD_SEC_CNT			212	/* RO, 4 bytes */
+#define EXT_CSD_S_A_TIMEOUT		217	/* RO */
+#define EXT_CSD_ERASE_TIMEOUT_MULT	223	/* RO */
+#define EXT_CSD_HC_ERASE_GRP_SIZE	224	/* RO */
+#define EXT_CSD_SEC_TRIM_MULT		229	/* RO */
+#define EXT_CSD_SEC_ERASE_MULT		230	/* RO */
+#define EXT_CSD_SEC_FEATURE_SUPPORT	231	/* RO */
+#define EXT_CSD_TRIM_MULT		232	/* RO */
 
 /*
  * EXT_CSD field definitions
@@ -265,11 +277,16 @@ struct _mmc_csd {
 
 #define EXT_CSD_CARD_TYPE_26	(1<<0)	/* Card can run at 26MHz */
 #define EXT_CSD_CARD_TYPE_52	(1<<1)	/* Card can run at 52MHz */
+#define EXT_CSD_CARD_TYPE_MASK	0x3	/* Mask out reserved and DDR bits */
 
 #define EXT_CSD_BUS_WIDTH_1	0	/* Card is in 1 bit mode */
 #define EXT_CSD_BUS_WIDTH_4	1	/* Card is in 4 bit mode */
 #define EXT_CSD_BUS_WIDTH_8	2	/* Card is in 8 bit mode */
 
+#define EXT_CSD_SEC_ER_EN	BIT(0)
+#define EXT_CSD_SEC_BD_BLK_EN	BIT(2)
+#define EXT_CSD_SEC_GB_CL_EN	BIT(4)
+
 /*
  * MMC_SWITCH access modes
  */
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 733d3f3..ff8a124 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -599,6 +599,12 @@ struct platform_nand_ctrl {
 	void		(*select_chip)(struct mtd_info *mtd, int chip);
 	void		(*cmd_ctrl)(struct mtd_info *mtd, int dat,
 				    unsigned int ctrl);
+	int 	(*calculate)(struct mtd_info *mtd,
+					 const uint8_t *dat,
+					 uint8_t *ecc_code);
+	int 		(*correct)(struct mtd_info *mtd, uint8_t *dat,
+					   uint8_t *read_ecc,
+					   uint8_t *calc_ecc);
 	void		*priv;
 };
 
