Merge branch 'orion' into devel

* orion: (26 commits)
  [ARM] Orion: implement power-off method for QNAP TS-109/209
  [ARM] Orion: add support for QNAP TS-109/TS-209
  [ARM] Orion: I2C support
  [I2C] i2c-mv64xxx: Don't set i2c_adapter.retries
  [I2C] Split mv643xx I2C platform support
  [ARM] Orion: enable CONFIG_RTC_DRV_M41T80 for D-Link DNS-323
  [ARM] Orion defconfig
  [ARM] Orion: add support for Orion/MV88F5181 based D-Link DNS-323
  [ARM] Orion: MV88F5181 support bits
  [ARM] Orion: Buffalo/Revogear Kurobox Pro support
  [ARM] OrionNAS RD board support
  [ARM] Orion: support for Marvell Orion-2 (88F5281) Development Board
  [ARM] Orion: common platform setup for Gigabit Ethernet port
  [ARM] Orion: platform device registration for UART, USB and NAND
  [ARM] Orion: system timer support
  [ARM] Orion edge GPIO IRQ support
  [ARM] Orion: IRQ support
  [ARM] Orion: provide GPIO method for enabling hardware assisted blinking
  [ARM] Orion: GPIO support
  [ARM] Orion: programable address map support
  ...

Conflicts:

	arch/arm/Kconfig
	arch/arm/Makefile

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e53b0ed..6835a4c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -334,6 +334,16 @@
 	help
 	  Support for Freescale MXC/iMX-based family of processors
 
+config ARCH_ORION
+	bool "Marvell Orion"
+	depends on MMU
+	select PCI
+	select GENERIC_GPIO
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+	help
+	  Support for Marvell Orion System on Chip family.
+
 config ARCH_PNX4008
 	bool "Philips Nexperia PNX4008 Mobile"
 	help
@@ -454,6 +464,8 @@
 
 source "arch/arm/mach-omap2/Kconfig"
 
+source "arch/arm/mach-orion/Kconfig"
+
 source "arch/arm/plat-s3c24xx/Kconfig"
 source "arch/arm/plat-s3c/Kconfig"
 
@@ -732,7 +744,7 @@
 		   ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
 		   ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
 		   ARCH_AT91 || MACH_TRIZEPS4 || ARCH_DAVINCI || \
-		   ARCH_KS8695
+		   ARCH_KS8695 || MACH_RD88F5182
 	help
 	  If you say Y here, the LEDs on your machine will be used
 	  to provide useful information about your current system status.
@@ -967,7 +979,7 @@
 
 config VFP
 	bool "VFP-format floating point maths"
-	depends on CPU_V6 || CPU_ARM926T || CPU_V7
+	depends on CPU_V6 || CPU_ARM926T || CPU_V7 || CPU_FEROCEON
 	help
 	  Say Y to include VFP support code in the kernel. This is needed
 	  if your hardware includes a VFP unit.
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index dd220d1..7b8ff66 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -139,6 +139,7 @@
  machine-$(CONFIG_ARCH_KS8695)     := ks8695
   incdir-$(CONFIG_ARCH_MXC)	   := mxc
  machine-$(CONFIG_ARCH_MX3)	   := mx3
+ machine-$(CONFIG_ARCH_ORION)	   := orion
  machine-$(CONFIG_ARCH_MSM7X00A)   := msm
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 5cac46a..3c2c8f2 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -623,6 +623,12 @@
 		b	__armv4_mmu_cache_off
 		b	__armv4_mmu_cache_flush
 
+		.word	0x56055310		@ Feroceon
+		.word	0xfffffff0
+		b	__armv4_mmu_cache_on
+		b	__armv4_mmu_cache_off
+		b	__armv5tej_mmu_cache_flush
+
 		@ These match on the architecture ID
 
 		.word	0x00020000		@ ARMv4T
@@ -641,7 +647,7 @@
 		.word	0x000f0000
 		b	__armv4_mmu_cache_on
 		b	__armv4_mmu_cache_off
-		b	__armv4_mmu_cache_flush
+		b	__armv5tej_mmu_cache_flush
 
 		.word	0x0007b000		@ ARMv6
 		.word	0x000ff000
@@ -821,6 +827,13 @@
 		mcr	p15, 0, r10, c7, c10, 4	@ drain WB
 		mov	pc, lr
 
+__armv5tej_mmu_cache_flush:
+1:		mrc	p15, 0, r15, c7, c14, 3	@ test,clean,invalidate D cache
+		bne	1b
+		mcr	p15, 0, r0, c7, c5, 0	@ flush I cache
+		mcr	p15, 0, r0, c7, c10, 4	@ drain WB
+		mov	pc, lr
+
 __armv4_mmu_cache_flush:
 		mov	r2, #64*1024		@ default: 32K dcache size (*2)
 		mov	r11, #32		@ default: 32 byte line size
diff --git a/arch/arm/configs/orion_defconfig b/arch/arm/configs/orion_defconfig
new file mode 100644
index 0000000..17a55de
--- /dev/null
+++ b/arch/arm/configs/orion_defconfig
@@ -0,0 +1,1384 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24-rc3
+# Wed Nov 28 15:13:57 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_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_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+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_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+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 is not set
+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
+
+#
+# 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"
+
+#
+# System Type
+#
+# 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_CO285 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_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+CONFIG_ARCH_ORION=y
+# 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
+
+#
+# Orion Implementations
+#
+CONFIG_MACH_DB88F5281=y
+CONFIG_MACH_RD88F5182=y
+CONFIG_MACH_KUROBOX_PRO=y
+CONFIG_MACH_DNS323=y
+CONFIG_MACH_TS209=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_FEROCEON=y
+CONFIG_CPU_FEROCEON_OLD_ID=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=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_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+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_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_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL 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_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 is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 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_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_FTL=y
+CONFIG_NFTL=y
+# CONFIG_NFTL_RW 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=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+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=y
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_CFI_UTIL=y
+# 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_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x0
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# 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=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE 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_NAND_ORION=y
+# 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_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# 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=y
+# CONFIG_BLK_DEV_SR_VENDOR 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=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+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 is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+CONFIG_SCSI_MVSATA=y
+
+#
+# Sata options
+#
+# CONFIG_MV_SATA_SUPPORT_ATAPI is not set
+# CONFIG_MV_SATA_ENABLE_1MB_IOS is not set
+CONFIG_SATA_NO_DEBUG=y
+# CONFIG_SATA_DEBUG_ON_ERROR is not set
+# CONFIG_SATA_FULL_DEBUG is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# 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_IP1000 is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+CONFIG_SKGE=y
+CONFIG_SKY2=y
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
+CONFIG_MV643XX_ETH=y
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 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_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER 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 is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE 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 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+CONFIG_I2C_MV64XXX=y
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 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
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER 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_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_ADT7470 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB 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_SIS5595 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_THMC50 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 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_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=y
+CONFIG_USB_SL811_HCD=y
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+CONFIG_USB_PRINTER=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# 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=y
+CONFIG_USB_STORAGE_FREECOM=y
+# CONFIG_USB_STORAGE_ISD200 is not set
+CONFIG_USB_STORAGE_DPCM=y
+# CONFIG_USB_STORAGE_USBAT is not set
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# 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_AUERSWALD 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
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_GPIO is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# 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=y
+# 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=y
+# 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=y
+# CONFIG_RTC_DRV_M41T80_WDT is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# 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 is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# 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_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_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=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_LDM_DEBUG=y
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+CONFIG_INSTRUMENTATION=y
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# 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_DEBUG_BUGVERBOSE is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+CONFIG_DEBUG_USER=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/mach-orion/Kconfig b/arch/arm/mach-orion/Kconfig
new file mode 100644
index 0000000..1dcbb6a
--- /dev/null
+++ b/arch/arm/mach-orion/Kconfig
@@ -0,0 +1,41 @@
+if ARCH_ORION
+
+menu "Orion Implementations"
+
+config MACH_DB88F5281
+	bool "Marvell Orion-2 Development Board"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell Orion-2 (88F5281) Development Board
+
+config MACH_RD88F5182
+	bool "Marvell Orion-NAS Reference Design"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell Orion-NAS (88F5182) RD2
+
+config MACH_KUROBOX_PRO
+	bool "KuroBox Pro"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  KuroBox Pro platform.
+
+config MACH_DNS323
+	bool "D-Link DNS-323"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  D-Link DNS-323 platform.
+
+config MACH_TS209
+	bool "QNAP TS-109/TS-209"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  QNAP TS-109/TS-209 platform.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile
new file mode 100644
index 0000000..f91d937
--- /dev/null
+++ b/arch/arm/mach-orion/Makefile
@@ -0,0 +1,6 @@
+obj-y				+= common.o addr-map.o pci.o gpio.o irq.o time.o
+obj-$(CONFIG_MACH_DB88F5281)	+= db88f5281-setup.o
+obj-$(CONFIG_MACH_RD88F5182)	+= rd88f5182-setup.o
+obj-$(CONFIG_MACH_KUROBOX_PRO)	+= kurobox_pro-setup.o
+obj-$(CONFIG_MACH_DNS323)	+= dns323-setup.o
+obj-$(CONFIG_MACH_TS209)	+= ts209-setup.o
diff --git a/arch/arm/mach-orion/Makefile.boot b/arch/arm/mach-orion/Makefile.boot
new file mode 100644
index 0000000..67039c3
--- /dev/null
+++ b/arch/arm/mach-orion/Makefile.boot
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
diff --git a/arch/arm/mach-orion/addr-map.c b/arch/arm/mach-orion/addr-map.c
new file mode 100644
index 0000000..488da38
--- /dev/null
+++ b/arch/arm/mach-orion/addr-map.c
@@ -0,0 +1,484 @@
+/*
+ * arch/arm/mach-orion/addr-map.c
+ *
+ * Address map functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/hardware.h>
+#include "common.h"
+
+/*
+ * The Orion has fully programable address map. There's a separate address
+ * map for each of the device _master_ interfaces, e.g. CPU, PCI, PCIE, USB,
+ * Gigabit Ethernet, DMA/XOR engines, etc. Each interface has its own
+ * address decode windows that allow it to access any of the Orion resources.
+ *
+ * CPU address decoding --
+ * Linux assumes that it is the boot loader that already setup the access to
+ * DDR and internal registers.
+ * Setup access to PCI and PCI-E IO/MEM space is issued by core.c.
+ * Setup access to various devices located on the device bus interface (e.g.
+ * flashes, RTC, etc) should be issued by machine-setup.c according to
+ * specific board population (by using orion_setup_cpu_win()).
+ *
+ * Non-CPU Masters address decoding --
+ * Unlike the CPU, we setup the access from Orion's master interfaces to DDR
+ * banks only (the typical use case).
+ * Setup access for each master to DDR is issued by common.c.
+ *
+ * Note: although orion_setbits() and orion_clrbits() are not atomic
+ * no locking is necessary here since code in this file is only called
+ * at boot time when there is no concurrency issues.
+ */
+
+/*
+ * Generic Address Decode Windows bit settings
+ */
+#define TARGET_DDR		0
+#define TARGET_PCI		3
+#define TARGET_PCIE		4
+#define TARGET_DEV_BUS		1
+#define ATTR_DDR_CS(n)		(((n) ==0) ? 0xe :	\
+				((n) == 1) ? 0xd :	\
+				((n) == 2) ? 0xb :	\
+				((n) == 3) ? 0x7 : 0xf)
+#define ATTR_PCIE_MEM		0x59
+#define ATTR_PCIE_IO		0x51
+#define ATTR_PCI_MEM		0x59
+#define ATTR_PCI_IO		0x51
+#define ATTR_DEV_CS0		0x1e
+#define ATTR_DEV_CS1		0x1d
+#define ATTR_DEV_CS2		0x1b
+#define ATTR_DEV_BOOT		0xf
+#define WIN_EN			1
+
+/*
+ * Helpers to get DDR banks info
+ */
+#define DDR_BASE_CS(n)		ORION_DDR_REG(0x1500 + ((n) * 8))
+#define DDR_SIZE_CS(n)		ORION_DDR_REG(0x1504 + ((n) * 8))
+#define DDR_MAX_CS		4
+#define DDR_REG_TO_SIZE(reg)	(((reg) | 0xffffff) + 1)
+#define DDR_REG_TO_BASE(reg)	((reg) & 0xff000000)
+#define DDR_BANK_EN		1
+
+/*
+ * CPU Address Decode Windows registers
+ */
+#define CPU_WIN_CTRL(n)		ORION_BRIDGE_REG(0x000 | ((n) << 4))
+#define CPU_WIN_BASE(n)		ORION_BRIDGE_REG(0x004 | ((n) << 4))
+#define CPU_WIN_REMAP_LO(n)	ORION_BRIDGE_REG(0x008 | ((n) << 4))
+#define CPU_WIN_REMAP_HI(n)	ORION_BRIDGE_REG(0x00c | ((n) << 4))
+#define CPU_MAX_WIN		8
+
+/*
+ * Use this CPU address decode windows allocation
+ */
+#define CPU_WIN_PCIE_IO		0
+#define CPU_WIN_PCI_IO		1
+#define CPU_WIN_PCIE_MEM	2
+#define CPU_WIN_PCI_MEM		3
+#define CPU_WIN_DEV_BOOT	4
+#define CPU_WIN_DEV_CS0		5
+#define CPU_WIN_DEV_CS1		6
+#define CPU_WIN_DEV_CS2		7
+
+/*
+ * PCIE Address Decode Windows registers
+ */
+#define PCIE_BAR_CTRL(n)	ORION_PCIE_REG(0x1804 + ((n - 1) * 4))
+#define PCIE_BAR_LO(n)		ORION_PCIE_REG(0x0010 + ((n) * 8))
+#define PCIE_BAR_HI(n)		ORION_PCIE_REG(0x0014 + ((n) * 8))
+#define PCIE_WIN_CTRL(n)	ORION_PCIE_REG(0x1820 + ((n) << 4))
+#define PCIE_WIN_BASE(n)	ORION_PCIE_REG(0x1824 + ((n) << 4))
+#define PCIE_WIN_REMAP(n)	ORION_PCIE_REG(0x182c + ((n) << 4))
+#define PCIE_DEFWIN_CTRL	ORION_PCIE_REG(0x18b0)
+#define PCIE_EXPROM_WIN_CTRL	ORION_PCIE_REG(0x18c0)
+#define PCIE_EXPROM_WIN_REMP	ORION_PCIE_REG(0x18c4)
+#define PCIE_MAX_BARS		3
+#define PCIE_MAX_WINS		5
+
+/*
+ * Use PCIE BAR '1' for all DDR banks
+ */
+#define PCIE_DRAM_BAR		1
+
+/*
+ * PCI Address Decode Windows registers
+ */
+#define PCI_BAR_SIZE_DDR_CS(n)	(((n) == 0) ? ORION_PCI_REG(0xc08) : \
+				((n) == 1) ? ORION_PCI_REG(0xd08) :  \
+				((n) == 2) ? ORION_PCI_REG(0xc0c) :  \
+				((n) == 3) ? ORION_PCI_REG(0xd0c) : 0)
+#define PCI_BAR_REMAP_DDR_CS(n)	(((n) ==0) ? ORION_PCI_REG(0xc48) : \
+				((n) == 1) ? ORION_PCI_REG(0xd48) :  \
+				((n) == 2) ? ORION_PCI_REG(0xc4c) :  \
+				((n) == 3) ? ORION_PCI_REG(0xd4c) : 0)
+#define PCI_BAR_ENABLE		ORION_PCI_REG(0xc3c)
+#define PCI_CTRL_BASE_LO(n)	ORION_PCI_REG(0x1e00 | ((n) << 4))
+#define PCI_CTRL_BASE_HI(n)	ORION_PCI_REG(0x1e04 | ((n) << 4))
+#define PCI_CTRL_SIZE(n)	ORION_PCI_REG(0x1e08 | ((n) << 4))
+#define PCI_ADDR_DECODE_CTRL	ORION_PCI_REG(0xd3c)
+
+/*
+ * PCI configuration heleprs for BAR settings
+ */
+#define PCI_CONF_FUNC_BAR_CS(n)		((n) >> 1)
+#define PCI_CONF_REG_BAR_LO_CS(n)	(((n) & 1) ? 0x18 : 0x10)
+#define PCI_CONF_REG_BAR_HI_CS(n)	(((n) & 1) ? 0x1c : 0x14)
+
+/*
+ * Gigabit Ethernet Address Decode Windows registers
+ */
+#define ETH_WIN_BASE(win)	ORION_ETH_REG(0x200 + ((win) * 8))
+#define ETH_WIN_SIZE(win)	ORION_ETH_REG(0x204 + ((win) * 8))
+#define ETH_WIN_REMAP(win)	ORION_ETH_REG(0x280 + ((win) * 4))
+#define ETH_WIN_EN		ORION_ETH_REG(0x290)
+#define ETH_WIN_PROT		ORION_ETH_REG(0x294)
+#define ETH_MAX_WIN		6
+#define ETH_MAX_REMAP_WIN	4
+
+/*
+ * USB Address Decode Windows registers
+ */
+#define USB_WIN_CTRL(i, w)	((i == 0) ? ORION_USB0_REG(0x320 + ((w) << 4)) \
+					: ORION_USB1_REG(0x320 + ((w) << 4)))
+#define USB_WIN_BASE(i, w)	((i == 0) ? ORION_USB0_REG(0x324 + ((w) << 4)) \
+					: ORION_USB1_REG(0x324 + ((w) << 4)))
+#define USB_MAX_WIN		4
+
+/*
+ * SATA Address Decode Windows registers
+ */
+#define SATA_WIN_CTRL(win)	ORION_SATA_REG(0x30 + ((win) * 0x10))
+#define SATA_WIN_BASE(win)	ORION_SATA_REG(0x34 + ((win) * 0x10))
+#define SATA_MAX_WIN		4
+
+static int __init orion_cpu_win_can_remap(u32 win)
+{
+	u32 dev, rev;
+
+	orion_pcie_id(&dev, &rev);
+	if ((dev == MV88F5281_DEV_ID && win < 4)
+	    || (dev == MV88F5182_DEV_ID && win < 2)
+	    || (dev == MV88F5181_DEV_ID && win < 2))
+		return 1;
+
+	return 0;
+}
+
+void __init orion_setup_cpu_win(enum orion_target target, u32 base, u32 size, int remap)
+{
+	u32 win, attr, ctrl;
+
+	switch (target) {
+	case ORION_PCIE_IO:
+		target = TARGET_PCIE;
+		attr = ATTR_PCIE_IO;
+		win = CPU_WIN_PCIE_IO;
+		break;
+	case ORION_PCI_IO:
+		target = TARGET_PCI;
+		attr = ATTR_PCI_IO;
+		win = CPU_WIN_PCI_IO;
+		break;
+	case ORION_PCIE_MEM:
+		target = TARGET_PCIE;
+		attr = ATTR_PCIE_MEM;
+		win = CPU_WIN_PCIE_MEM;
+		break;
+	case ORION_PCI_MEM:
+		target = TARGET_PCI;
+		attr = ATTR_PCI_MEM;
+		win = CPU_WIN_PCI_MEM;
+		break;
+	case ORION_DEV_BOOT:
+		target = TARGET_DEV_BUS;
+		attr = ATTR_DEV_BOOT;
+		win = CPU_WIN_DEV_BOOT;
+		break;
+	case ORION_DEV0:
+		target = TARGET_DEV_BUS;
+		attr = ATTR_DEV_CS0;
+		win = CPU_WIN_DEV_CS0;
+		break;
+	case ORION_DEV1:
+		target = TARGET_DEV_BUS;
+		attr = ATTR_DEV_CS1;
+		win = CPU_WIN_DEV_CS1;
+		break;
+	case ORION_DEV2:
+		target = TARGET_DEV_BUS;
+		attr = ATTR_DEV_CS2;
+		win = CPU_WIN_DEV_CS2;
+		break;
+	case ORION_DDR:
+	case ORION_REGS:
+		/*
+		 * Must be mapped by bootloader.
+		 */
+	default:
+		target = attr = win = -1;
+		BUG();
+	}
+
+	base &= 0xffff0000;
+	ctrl = (((size - 1) & 0xffff0000) | (attr << 8) |
+		(target << 4) | WIN_EN);
+
+	orion_write(CPU_WIN_BASE(win), base);
+	orion_write(CPU_WIN_CTRL(win), ctrl);
+
+	if (orion_cpu_win_can_remap(win)) {
+		if (remap >= 0) {
+			orion_write(CPU_WIN_REMAP_LO(win), remap & 0xffff0000);
+			orion_write(CPU_WIN_REMAP_HI(win), 0);
+		} else {
+			orion_write(CPU_WIN_REMAP_LO(win), base);
+			orion_write(CPU_WIN_REMAP_HI(win), 0);
+		}
+	}
+}
+
+void __init orion_setup_cpu_wins(void)
+{
+	int i;
+
+	/*
+	 * First, disable and clear windows
+	 */
+	for (i = 0; i < CPU_MAX_WIN; i++) {
+		orion_write(CPU_WIN_BASE(i), 0);
+		orion_write(CPU_WIN_CTRL(i), 0);
+		if (orion_cpu_win_can_remap(i)) {
+			orion_write(CPU_WIN_REMAP_LO(i), 0);
+			orion_write(CPU_WIN_REMAP_HI(i), 0);
+		}
+	}
+
+	/*
+	 * Setup windows for PCI+PCIE IO+MAM space
+	 */
+	orion_setup_cpu_win(ORION_PCIE_IO, ORION_PCIE_IO_BASE,
+				ORION_PCIE_IO_SIZE, ORION_PCIE_IO_REMAP);
+	orion_setup_cpu_win(ORION_PCI_IO, ORION_PCI_IO_BASE,
+				ORION_PCI_IO_SIZE, ORION_PCI_IO_REMAP);
+	orion_setup_cpu_win(ORION_PCIE_MEM, ORION_PCIE_MEM_BASE,
+				ORION_PCIE_MEM_SIZE, -1);
+	orion_setup_cpu_win(ORION_PCI_MEM, ORION_PCI_MEM_BASE,
+				ORION_PCI_MEM_SIZE, -1);
+}
+
+/*
+ * Setup PCIE BARs and Address Decode Wins:
+ * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
+ * WIN[0-3] -> DRAM bank[0-3]
+ */
+void __init orion_setup_pcie_wins(void)
+{
+	u32 base, size, i;
+
+	/*
+	 * First, disable and clear BARs and windows
+	 */
+	for (i = 1; i < PCIE_MAX_BARS; i++) {
+		orion_write(PCIE_BAR_CTRL(i), 0);
+		orion_write(PCIE_BAR_LO(i), 0);
+		orion_write(PCIE_BAR_HI(i), 0);
+	}
+
+	for (i = 0; i < PCIE_MAX_WINS; i++) {
+		orion_write(PCIE_WIN_CTRL(i), 0);
+		orion_write(PCIE_WIN_BASE(i), 0);
+		orion_write(PCIE_WIN_REMAP(i), 0);
+	}
+
+	/*
+	 * Setup windows for DDR banks. Count total DDR size on the fly.
+	 */
+	base = DDR_REG_TO_BASE(orion_read(DDR_BASE_CS(0)));
+	size = 0;
+	for (i = 0; i < DDR_MAX_CS; i++) {
+		u32 bank_base, bank_size;
+		bank_size = orion_read(DDR_SIZE_CS(i));
+		bank_base = orion_read(DDR_BASE_CS(i));
+		if (bank_size & DDR_BANK_EN) {
+			bank_size = DDR_REG_TO_SIZE(bank_size);
+			bank_base = DDR_REG_TO_BASE(bank_base);
+			orion_write(PCIE_WIN_BASE(i), bank_base & 0xffff0000);
+			orion_write(PCIE_WIN_REMAP(i), 0);
+			orion_write(PCIE_WIN_CTRL(i),
+					((bank_size-1) & 0xffff0000) |
+					(ATTR_DDR_CS(i) << 8) |
+					(TARGET_DDR << 4) |
+					(PCIE_DRAM_BAR << 1) | WIN_EN);
+			size += bank_size;
+		}
+	}
+
+	/*
+	 * Setup BAR[1] to all DRAM banks
+	 */
+	orion_write(PCIE_BAR_LO(PCIE_DRAM_BAR), base & 0xffff0000);
+	orion_write(PCIE_BAR_HI(PCIE_DRAM_BAR), 0);
+	orion_write(PCIE_BAR_CTRL(PCIE_DRAM_BAR),
+				((size - 1) & 0xffff0000) | WIN_EN);
+}
+
+void __init orion_setup_pci_wins(void)
+{
+	u32 base, size, i;
+
+	/*
+	 * First, disable windows
+	 */
+	orion_write(PCI_BAR_ENABLE, 0xffffffff);
+
+	/*
+	 * Setup windows for DDR banks.
+	 */
+	for (i = 0; i < DDR_MAX_CS; i++) {
+		base = orion_read(DDR_BASE_CS(i));
+		size = orion_read(DDR_SIZE_CS(i));
+		if (size & DDR_BANK_EN) {
+			u32 bus, dev, func, reg, val;
+			size = DDR_REG_TO_SIZE(size);
+			base = DDR_REG_TO_BASE(base);
+			bus = orion_pci_local_bus_nr();
+			dev = orion_pci_local_dev_nr();
+			func = PCI_CONF_FUNC_BAR_CS(i);
+			reg = PCI_CONF_REG_BAR_LO_CS(i);
+			orion_pci_hw_rd_conf(bus, dev, func, reg, 4, &val);
+			orion_pci_hw_wr_conf(bus, dev, func, reg, 4,
+					(base & 0xfffff000) | (val & 0xfff));
+			reg = PCI_CONF_REG_BAR_HI_CS(i);
+			orion_pci_hw_wr_conf(bus, dev, func, reg, 4, 0);
+			orion_write(PCI_BAR_SIZE_DDR_CS(i),
+					(size - 1) & 0xfffff000);
+			orion_write(PCI_BAR_REMAP_DDR_CS(i),
+					base & 0xfffff000);
+			orion_clrbits(PCI_BAR_ENABLE, (1 << i));
+		}
+	}
+
+	/*
+	 * Disable automatic update of address remaping when writing to BARs
+	 */
+	orion_setbits(PCI_ADDR_DECODE_CTRL, 1);
+}
+
+void __init orion_setup_usb_wins(void)
+{
+	int i;
+	u32 usb_if, dev, rev;
+	u32 max_usb_if = 1;
+
+	orion_pcie_id(&dev, &rev);
+	if (dev == MV88F5182_DEV_ID)
+		max_usb_if = 2;
+
+	for (usb_if = 0; usb_if < max_usb_if; usb_if++) {
+		/*
+		 * First, disable and clear windows
+		 */
+		for (i = 0; i < USB_MAX_WIN; i++) {
+			orion_write(USB_WIN_BASE(usb_if, i), 0);
+			orion_write(USB_WIN_CTRL(usb_if, i), 0);
+		}
+
+		/*
+		 * Setup windows for DDR banks.
+		 */
+		for (i = 0; i < DDR_MAX_CS; i++) {
+			u32 base, size;
+			size = orion_read(DDR_SIZE_CS(i));
+			base = orion_read(DDR_BASE_CS(i));
+			if (size & DDR_BANK_EN) {
+				base = DDR_REG_TO_BASE(base);
+				size = DDR_REG_TO_SIZE(size);
+				orion_write(USB_WIN_CTRL(usb_if, i),
+						((size-1) & 0xffff0000) |
+						(ATTR_DDR_CS(i) << 8) |
+						(TARGET_DDR << 4) | WIN_EN);
+				orion_write(USB_WIN_BASE(usb_if, i),
+						base & 0xffff0000);
+			}
+		}
+	}
+}
+
+void __init orion_setup_eth_wins(void)
+{
+	int i;
+
+	/*
+	 * First, disable and clear windows
+	 */
+	for (i = 0; i < ETH_MAX_WIN; i++) {
+		orion_write(ETH_WIN_BASE(i), 0);
+		orion_write(ETH_WIN_SIZE(i), 0);
+		orion_setbits(ETH_WIN_EN, 1 << i);
+		orion_clrbits(ETH_WIN_PROT, 0x3 << (i * 2));
+		if (i < ETH_MAX_REMAP_WIN)
+			orion_write(ETH_WIN_REMAP(i), 0);
+	}
+
+	/*
+	 * Setup windows for DDR banks.
+	 */
+	for (i = 0; i < DDR_MAX_CS; i++) {
+		u32 base, size;
+		size = orion_read(DDR_SIZE_CS(i));
+		base = orion_read(DDR_BASE_CS(i));
+		if (size & DDR_BANK_EN) {
+			base = DDR_REG_TO_BASE(base);
+			size = DDR_REG_TO_SIZE(size);
+			orion_write(ETH_WIN_SIZE(i), (size-1) & 0xffff0000);
+			orion_write(ETH_WIN_BASE(i), (base & 0xffff0000) |
+					(ATTR_DDR_CS(i) << 8) |
+					TARGET_DDR);
+			orion_clrbits(ETH_WIN_EN, 1 << i);
+			orion_setbits(ETH_WIN_PROT, 0x3 << (i * 2));
+		}
+	}
+}
+
+void __init orion_setup_sata_wins(void)
+{
+	int i;
+
+	/*
+	 * First, disable and clear windows
+	 */
+	for (i = 0; i < SATA_MAX_WIN; i++) {
+		orion_write(SATA_WIN_BASE(i), 0);
+		orion_write(SATA_WIN_CTRL(i), 0);
+	}
+
+	/*
+	 * Setup windows for DDR banks.
+	 */
+	for (i = 0; i < DDR_MAX_CS; i++) {
+		u32 base, size;
+		size = orion_read(DDR_SIZE_CS(i));
+		base = orion_read(DDR_BASE_CS(i));
+		if (size & DDR_BANK_EN) {
+			base = DDR_REG_TO_BASE(base);
+			size = DDR_REG_TO_SIZE(size);
+			orion_write(SATA_WIN_CTRL(i),
+					((size-1) & 0xffff0000) |
+					(ATTR_DDR_CS(i) << 8) |
+					(TARGET_DDR << 4) | WIN_EN);
+			orion_write(SATA_WIN_BASE(i),
+					base & 0xffff0000);
+		}
+	}
+}
diff --git a/arch/arm/mach-orion/common.c b/arch/arm/mach-orion/common.c
new file mode 100644
index 0000000..5e20b6b
--- /dev/null
+++ b/arch/arm/mach-orion/common.c
@@ -0,0 +1,315 @@
+/*
+ * arch/arm/mach-orion/common.c
+ *
+ * Core functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/mv643xx_i2c.h>
+#include <asm/page.h>
+#include <asm/timex.h>
+#include <asm/mach/map.h>
+#include <asm/arch/orion.h>
+#include "common.h"
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc orion_io_desc[] __initdata = {
+	{
+		.virtual	= ORION_REGS_BASE,
+		.pfn		= __phys_to_pfn(ORION_REGS_BASE),
+		.length		= ORION_REGS_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= ORION_PCIE_IO_BASE,
+		.pfn		= __phys_to_pfn(ORION_PCIE_IO_BASE),
+		.length		= ORION_PCIE_IO_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= ORION_PCI_IO_BASE,
+		.pfn		= __phys_to_pfn(ORION_PCI_IO_BASE),
+		.length		= ORION_PCI_IO_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= ORION_PCIE_WA_BASE,
+		.pfn		= __phys_to_pfn(ORION_PCIE_WA_BASE),
+		.length		= ORION_PCIE_WA_SIZE,
+		.type		= MT_DEVICE
+	},
+};
+
+void __init orion_map_io(void)
+{
+	iotable_init(orion_io_desc, ARRAY_SIZE(orion_io_desc));
+}
+
+/*****************************************************************************
+ * UART
+ ****************************************************************************/
+
+static struct resource orion_uart_resources[] = {
+	{
+		.start		= UART0_BASE,
+		.end		= UART0_BASE + 0xff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= IRQ_ORION_UART0,
+		.end		= IRQ_ORION_UART0,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= UART1_BASE,
+		.end		= UART1_BASE + 0xff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= IRQ_ORION_UART1,
+		.end		= IRQ_ORION_UART1,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct plat_serial8250_port orion_uart_data[] = {
+	{
+		.mapbase	= UART0_BASE,
+		.membase	= (char *)UART0_BASE,
+		.irq		= IRQ_ORION_UART0,
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= ORION_TCLK,
+	},
+	{
+		.mapbase	= UART1_BASE,
+		.membase	= (char *)UART1_BASE,
+		.irq		= IRQ_ORION_UART1,
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= ORION_TCLK,
+	},
+	{ },
+};
+
+static struct platform_device orion_uart = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= orion_uart_data,
+	},
+	.resource		= orion_uart_resources,
+	.num_resources		= ARRAY_SIZE(orion_uart_resources),
+};
+
+/*******************************************************************************
+ * USB Controller - 2 interfaces
+ ******************************************************************************/
+
+static struct resource orion_ehci0_resources[] = {
+	{
+		.start	= ORION_USB0_REG_BASE,
+		.end	= ORION_USB0_REG_BASE + SZ_4K,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_ORION_USB0_CTRL,
+		.end	= IRQ_ORION_USB0_CTRL,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource orion_ehci1_resources[] = {
+	{
+		.start	= ORION_USB1_REG_BASE,
+		.end	= ORION_USB1_REG_BASE + SZ_4K,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_ORION_USB1_CTRL,
+		.end	= IRQ_ORION_USB1_CTRL,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 ehci_dmamask = 0xffffffffUL;
+
+static struct platform_device orion_ehci0 = {
+	.name		= "orion-ehci",
+	.id		= 0,
+	.dev		= {
+		.dma_mask		= &ehci_dmamask,
+		.coherent_dma_mask	= 0xffffffff,
+	},
+	.resource	= orion_ehci0_resources,
+	.num_resources	= ARRAY_SIZE(orion_ehci0_resources),
+};
+
+static struct platform_device orion_ehci1 = {
+	.name		= "orion-ehci",
+	.id		= 1,
+	.dev		= {
+		.dma_mask		= &ehci_dmamask,
+		.coherent_dma_mask	= 0xffffffff,
+	},
+	.resource	= orion_ehci1_resources,
+	.num_resources	= ARRAY_SIZE(orion_ehci1_resources),
+};
+
+/*****************************************************************************
+ * Gigabit Ethernet port
+ * (The Orion and Discovery (MV643xx) families use the same Ethernet driver)
+ ****************************************************************************/
+
+static struct resource orion_eth_shared_resources[] = {
+	{
+		.start	= ORION_ETH_REG_BASE,
+		.end	= ORION_ETH_REG_BASE + 0xffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device orion_eth_shared = {
+	.name		= MV643XX_ETH_SHARED_NAME,
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= orion_eth_shared_resources,
+};
+
+static struct resource orion_eth_resources[] = {
+	{
+		.name	= "eth irq",
+		.start	= IRQ_ORION_ETH_SUM,
+		.end	= IRQ_ORION_ETH_SUM,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device orion_eth = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= orion_eth_resources,
+};
+
+void __init orion_eth_init(struct mv643xx_eth_platform_data *eth_data)
+{
+	orion_eth.dev.platform_data = eth_data;
+	platform_device_register(&orion_eth_shared);
+	platform_device_register(&orion_eth);
+}
+
+/*****************************************************************************
+ * I2C controller
+ * (The Orion and Discovery (MV643xx) families share the same I2C controller)
+ ****************************************************************************/
+
+static struct mv64xxx_i2c_pdata orion_i2c_pdata = {
+	.freq_m		= 8, /* assumes 166 MHz TCLK */
+	.freq_n		= 3,
+	.timeout	= 1000, /* Default timeout of 1 second */
+};
+
+static struct resource orion_i2c_resources[] = {
+	{
+		.name   = "i2c base",
+		.start  = I2C_BASE,
+		.end    = I2C_BASE + 0x20 -1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "i2c irq",
+		.start  = IRQ_ORION_I2C,
+		.end    = IRQ_ORION_I2C,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device orion_i2c = {
+	.name		= MV64XXX_I2C_CTLR_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(orion_i2c_resources),
+	.resource	= orion_i2c_resources,
+	.dev		= {
+		.platform_data = &orion_i2c_pdata,
+	},
+};
+
+/*****************************************************************************
+ * General
+ ****************************************************************************/
+
+/*
+ * Identify device ID and rev from PCIE configuration header space '0'.
+ */
+static void orion_id(u32 *dev, u32 *rev, char **dev_name)
+{
+	orion_pcie_id(dev, rev);
+
+	if (*dev == MV88F5281_DEV_ID) {
+		if (*rev == MV88F5281_REV_D2) {
+			*dev_name = "MV88F5281-D2";
+		} else if (*rev == MV88F5281_REV_D1) {
+			*dev_name = "MV88F5281-D1";
+		} else {
+			*dev_name = "MV88F5281-Rev-Unsupported";
+		}
+	} else if (*dev == MV88F5182_DEV_ID) {
+		if (*rev == MV88F5182_REV_A2) {
+			*dev_name = "MV88F5182-A2";
+		} else {
+			*dev_name = "MV88F5182-Rev-Unsupported";
+		}
+	} else if (*dev == MV88F5181_DEV_ID) {
+		if (*rev == MV88F5181_REV_B1) {
+			*dev_name = "MV88F5181-Rev-B1";
+		} else {
+			*dev_name = "MV88F5181-Rev-Unsupported";
+		}
+	} else {
+		*dev_name = "Device-Unknown";
+	}
+}
+
+void __init orion_init(void)
+{
+	char *dev_name;
+	u32 dev, rev;
+
+	orion_id(&dev, &rev, &dev_name);
+	printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, ORION_TCLK);
+
+	/*
+	 * Setup Orion address map
+	 */
+	orion_setup_cpu_wins();
+	orion_setup_usb_wins();
+	orion_setup_eth_wins();
+	orion_setup_pci_wins();
+	orion_setup_pcie_wins();
+	if (dev == MV88F5182_DEV_ID)
+		orion_setup_sata_wins();
+
+	/*
+	 * REgister devices
+	 */
+	platform_device_register(&orion_uart);
+	platform_device_register(&orion_ehci0);
+	if (dev == MV88F5182_DEV_ID)
+		platform_device_register(&orion_ehci1);
+	platform_device_register(&orion_i2c);
+}
diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h
new file mode 100644
index 0000000..06c10c0
--- /dev/null
+++ b/arch/arm/mach-orion/common.h
@@ -0,0 +1,78 @@
+#ifndef __ARCH_ORION_COMMON_H__
+#define __ARCH_ORION_COMMON_H__
+
+/*
+ * Basic Orion init functions used early by machine-setup.
+ */
+
+void __init orion_map_io(void);
+void __init orion_init_irq(void);
+void __init orion_init(void);
+
+/*
+ * Enumerations and functions for Orion windows mapping. Used by Orion core
+ * functions to map its interfaces and by the machine-setup to map its on-
+ * board devices. Details in /mach-orion/addr-map.c
+ */
+
+enum orion_target {
+	ORION_DEV_BOOT = 0,
+	ORION_DEV0,
+	ORION_DEV1,
+	ORION_DEV2,
+	ORION_PCIE_MEM,
+	ORION_PCIE_IO,
+	ORION_PCI_MEM,
+	ORION_PCI_IO,
+	ORION_DDR,
+	ORION_REGS,
+	ORION_MAX_TARGETS
+};
+
+void orion_setup_cpu_win(enum orion_target target, u32 base, u32 size, int remap);
+void orion_setup_cpu_wins(void);
+void orion_setup_eth_wins(void);
+void orion_setup_usb_wins(void);
+void orion_setup_pci_wins(void);
+void orion_setup_pcie_wins(void);
+void orion_setup_sata_wins(void);
+
+/*
+ * Shared code used internally by other Orion core functions.
+ * (/mach-orion/pci.c)
+ */
+
+struct pci_sys_data;
+struct pci_bus;
+
+void orion_pcie_id(u32 *dev, u32 *rev);
+u32 orion_pcie_local_bus_nr(void);
+u32 orion_pci_local_bus_nr(void);
+u32 orion_pci_local_dev_nr(void);
+int orion_pci_sys_setup(int nr, struct pci_sys_data *sys);
+struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys);
+int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 *val);
+int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 val);
+
+/*
+ * Valid GPIO pins according to MPP setup, used by machine-setup.
+ * (/mach-orion/gpio.c).
+ */
+
+void __init orion_gpio_set_valid_pins(u32 pins);
+void gpio_display(void);	/* debug */
+
+/*
+ * Orion system timer (clocksource + clockevnt, /mach-orion/time.c)
+ */
+extern struct sys_timer orion_timer;
+
+/*
+ * Pull in Orion Ethernet platform_data, used by machine-setup
+ */
+
+struct mv643xx_eth_platform_data;
+
+void __init orion_eth_init(struct mv643xx_eth_platform_data *eth_data);
+
+#endif /* __ARCH_ORION_COMMON_H__ */
diff --git a/arch/arm/mach-orion/db88f5281-setup.c b/arch/arm/mach-orion/db88f5281-setup.c
new file mode 100644
index 0000000..cb2a95c
--- /dev/null
+++ b/arch/arm/mach-orion/db88f5281-setup.c
@@ -0,0 +1,364 @@
+/*
+ * arch/arm/mach-orion/db88f5281-setup.c
+ *
+ * Marvell Orion-2 Development Board Setup
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/timer.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/orion.h>
+#include <asm/arch/platform.h>
+#include "common.h"
+
+/*****************************************************************************
+ * DB-88F5281 on board devices
+ ****************************************************************************/
+
+/*
+ * 512K NOR flash Device bus boot chip select
+ */
+
+#define DB88F5281_NOR_BOOT_BASE		0xf4000000
+#define DB88F5281_NOR_BOOT_SIZE		SZ_512K
+
+/*
+ * 7-Segment on Device bus chip select 0
+ */
+
+#define DB88F5281_7SEG_BASE		0xfa000000
+#define DB88F5281_7SEG_SIZE		SZ_1K
+
+/*
+ * 32M NOR flash on Device bus chip select 1
+ */
+
+#define DB88F5281_NOR_BASE		0xfc000000
+#define DB88F5281_NOR_SIZE		SZ_32M
+
+/*
+ * 32M NAND flash on Device bus chip select 2
+ */
+
+#define DB88F5281_NAND_BASE		0xfa800000
+#define DB88F5281_NAND_SIZE		SZ_1K
+
+/*
+ * PCI
+ */
+
+#define DB88F5281_PCI_SLOT0_OFFS		7
+#define DB88F5281_PCI_SLOT0_IRQ_PIN		12
+#define DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN	13
+
+/*****************************************************************************
+ * 512M NOR Flash on Device bus Boot CS
+ ****************************************************************************/
+
+static struct physmap_flash_data db88f5281_boot_flash_data = {
+	.width		= 1,	/* 8 bit bus width */
+};
+
+static struct resource db88f5281_boot_flash_resource = {
+	.flags		= IORESOURCE_MEM,
+	.start		= DB88F5281_NOR_BOOT_BASE,
+	.end		= DB88F5281_NOR_BOOT_BASE + DB88F5281_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device db88f5281_boot_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+		.platform_data = &db88f5281_boot_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &db88f5281_boot_flash_resource,
+};
+
+/*****************************************************************************
+ * 32M NOR Flash on Device bus CS1
+ ****************************************************************************/
+
+static struct physmap_flash_data db88f5281_nor_flash_data = {
+	.width		= 4,	/* 32 bit bus width */
+};
+
+static struct resource db88f5281_nor_flash_resource = {
+	.flags		= IORESOURCE_MEM,
+	.start		= DB88F5281_NOR_BASE,
+	.end		= DB88F5281_NOR_BASE + DB88F5281_NOR_SIZE - 1,
+};
+
+static struct platform_device db88f5281_nor_flash = {
+	.name		= "physmap-flash",
+	.id		= 1,
+	.dev		= {
+		.platform_data = &db88f5281_nor_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &db88f5281_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * 32M NAND Flash on Device bus CS2
+ ****************************************************************************/
+
+static struct mtd_partition db88f5281_nand_parts[] = {
+	{
+		.name = "kernel",
+		.offset = 0,
+		.size = SZ_2M,
+	},
+	{
+		.name = "root",
+		.offset = SZ_2M,
+		.size = (SZ_16M - SZ_2M),
+	},
+	{
+		.name = "user",
+		.offset = SZ_16M,
+		.size = SZ_8M,
+	},
+	{
+		.name = "recovery",
+		.offset = (SZ_16M + SZ_8M),
+		.size = SZ_8M,
+	},
+};
+
+static struct resource db88f5281_nand_resource = {
+	.flags		= IORESOURCE_MEM,
+	.start		= DB88F5281_NAND_BASE,
+	.end		= DB88F5281_NAND_BASE + DB88F5281_NAND_SIZE - 1,
+};
+
+static struct orion_nand_data db88f5281_nand_data = {
+	.parts		= db88f5281_nand_parts,
+	.nr_parts	= ARRAY_SIZE(db88f5281_nand_parts),
+	.cle		= 0,
+	.ale		= 1,
+	.width		= 8,
+};
+
+static struct platform_device db88f5281_nand_flash = {
+	.name		= "orion_nand",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &db88f5281_nand_data,
+	},
+	.resource	= &db88f5281_nand_resource,
+	.num_resources	= 1,
+};
+
+/*****************************************************************************
+ * 7-Segment on Device bus CS0
+ * Dummy counter every 2 sec
+ ****************************************************************************/
+
+static void __iomem *db88f5281_7seg;
+static struct timer_list db88f5281_timer;
+
+static void db88f5281_7seg_event(unsigned long data)
+{
+	static int count = 0;
+	writel(0, db88f5281_7seg + (count << 4));
+	count = (count + 1) & 7;
+	mod_timer(&db88f5281_timer, jiffies + 2 * HZ);
+}
+
+static int __init db88f5281_7seg_init(void)
+{
+	if (machine_is_db88f5281()) {
+		db88f5281_7seg = ioremap(DB88F5281_7SEG_BASE,
+					DB88F5281_7SEG_SIZE);
+		if (!db88f5281_7seg) {
+			printk(KERN_ERR "Failed to ioremap db88f5281_7seg\n");
+			return -EIO;
+		}
+		setup_timer(&db88f5281_timer, db88f5281_7seg_event, 0);
+		mod_timer(&db88f5281_timer, jiffies + 2 * HZ);
+	}
+
+	return 0;
+}
+
+__initcall(db88f5281_7seg_init);
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+void __init db88f5281_pci_preinit(void)
+{
+	int pin;
+
+	/*
+	 * Configure PCI GPIO IRQ pins
+	 */
+	pin = DB88F5281_PCI_SLOT0_IRQ_PIN;
+	if (gpio_request(pin, "PCI Int1") == 0) {
+		if (gpio_direction_input(pin) == 0) {
+			set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+		} else {
+			printk(KERN_ERR "db88f5281_pci_preinit faield to "
+					"set_irq_type pin %d\n", pin);
+			gpio_free(pin);
+		}
+	} else {
+		printk(KERN_ERR "db88f5281_pci_preinit failed to gpio_request %d\n", pin);
+	}
+
+	pin = DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN;
+	if (gpio_request(pin, "PCI Int2") == 0) {
+		if (gpio_direction_input(pin) == 0) {
+			set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+		} else {
+			printk(KERN_ERR "db88f5281_pci_preinit faield "
+					"to set_irq_type pin %d\n", pin);
+			gpio_free(pin);
+		}
+	} else {
+		printk(KERN_ERR "db88f5281_pci_preinit failed to gpio_request %d\n", pin);
+	}
+}
+
+static int __init db88f5281_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/*
+	 * PCIE IRQ is connected internally (not GPIO)
+	 */
+	if (dev->bus->number == orion_pcie_local_bus_nr())
+		return IRQ_ORION_PCIE0_INT;
+
+	/*
+	 * PCI IRQs are connected via GPIOs
+	 */
+	switch (slot - DB88F5281_PCI_SLOT0_OFFS) {
+	case 0:
+		return gpio_to_irq(DB88F5281_PCI_SLOT0_IRQ_PIN);
+	case 1:
+	case 2:
+		return gpio_to_irq(DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN);
+	default:
+		return -1;
+	}
+}
+
+static struct hw_pci db88f5281_pci __initdata = {
+	.nr_controllers	= 2,
+	.preinit	= db88f5281_pci_preinit,
+	.swizzle	= pci_std_swizzle,
+	.setup		= orion_pci_sys_setup,
+	.scan		= orion_pci_sys_scan_bus,
+	.map_irq	= db88f5281_pci_map_irq,
+};
+
+static int __init db88f5281_pci_init(void)
+{
+	if (machine_is_db88f5281())
+		pci_common_init(&db88f5281_pci);
+
+	return 0;
+}
+
+subsys_initcall(db88f5281_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+static struct mv643xx_eth_platform_data db88f5281_eth_data = {
+	.phy_addr	= 8,
+	.force_phy_addr = 1,
+};
+
+/*****************************************************************************
+ * RTC DS1339 on I2C bus
+ ****************************************************************************/
+static struct i2c_board_info __initdata db88f5281_i2c_rtc = {
+	.driver_name	= "rtc-ds1307",
+	.type		= "ds1339",
+	.addr		= 0x68,
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static struct platform_device *db88f5281_devs[] __initdata = {
+	&db88f5281_boot_flash,
+	&db88f5281_nor_flash,
+	&db88f5281_nand_flash,
+};
+
+static void __init db88f5281_init(void)
+{
+	/*
+	 * Basic Orion setup. Need to be called early.
+	 */
+	orion_init();
+
+	/*
+	 * Setup the CPU address decode windows for our on-board devices
+	 */
+	orion_setup_cpu_win(ORION_DEV_BOOT, DB88F5281_NOR_BOOT_BASE,
+				DB88F5281_NOR_BOOT_SIZE, -1);
+	orion_setup_cpu_win(ORION_DEV0,	DB88F5281_7SEG_BASE,
+				DB88F5281_7SEG_SIZE, -1);
+	orion_setup_cpu_win(ORION_DEV1, DB88F5281_NOR_BASE,
+				DB88F5281_NOR_SIZE, -1);
+	orion_setup_cpu_win(ORION_DEV2,	DB88F5281_NAND_BASE,
+				DB88F5281_NAND_SIZE, -1);
+
+	/*
+	 * Setup Multiplexing Pins:
+	 * MPP0: GPIO (USB Over Current)	MPP1: GPIO (USB Vbat input)
+	 * MPP2: PCI_REQn[2]			MPP3: PCI_GNTn[2]
+	 * MPP4: PCI_REQn[3]			MPP5: PCI_GNTn[3]
+	 * MPP6: GPIO (JP0, CON17.2)		MPP7: GPIO (JP1, CON17.1)
+	 * MPP8: GPIO (JP2, CON11.2)		MPP9: GPIO (JP3, CON11.3)
+	 * MPP10: GPIO (RTC int)		MPP11: GPIO (Baud Rate Generator)
+	 * MPP12: GPIO (PCI int 1)		MPP13: GPIO (PCI int 2)
+	 * MPP14: NAND_REn[2]			MPP15: NAND_WEn[2]
+	 * MPP16: UART1_RX			MPP17: UART1_TX
+	 * MPP18: UART1_CTS			MPP19: UART1_RTS
+	 * MPP-DEV: DEV_D[16:31]
+	 */
+	orion_write(MPP_0_7_CTRL, 0x00222203);
+	orion_write(MPP_8_15_CTRL, 0x44000000);
+	orion_write(MPP_16_19_CTRL, 0);
+	orion_write(MPP_DEV_CTRL, 0);
+
+	orion_gpio_set_valid_pins(0x00003fc3);
+
+	platform_add_devices(db88f5281_devs, ARRAY_SIZE(db88f5281_devs));
+	i2c_register_board_info(0, &db88f5281_i2c_rtc, 1);
+	orion_eth_init(&db88f5281_eth_data);
+}
+
+MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board")
+	/* Maintainer: Tzachi Perelstein <tzachi@marvell.com> */
+	.phys_io	= ORION_REGS_BASE,
+	.io_pg_offst	= ((ORION_REGS_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= db88f5281_init,
+	.map_io		= orion_map_io,
+	.init_irq	= orion_init_irq,
+	.timer		= &orion_timer,
+MACHINE_END
diff --git a/arch/arm/mach-orion/dns323-setup.c b/arch/arm/mach-orion/dns323-setup.c
new file mode 100644
index 0000000..c8a806f
--- /dev/null
+++ b/arch/arm/mach-orion/dns323-setup.c
@@ -0,0 +1,322 @@
+/*
+ * arch/arm/mach-orion/dns323-setup.c
+ *
+ * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/orion.h>
+#include <asm/arch/platform.h>
+#include "common.h"
+
+#define DNS323_GPIO_LED_RIGHT_AMBER	1
+#define DNS323_GPIO_LED_LEFT_AMBER	2
+#define DNS323_GPIO_LED_POWER		5
+#define DNS323_GPIO_OVERTEMP		6
+#define DNS323_GPIO_RTC			7
+#define DNS323_GPIO_POWER_OFF		8
+#define DNS323_GPIO_KEY_POWER		9
+#define DNS323_GPIO_KEY_RESET		10
+
+/****************************************************************************
+ * PCI setup
+ */
+
+static int __init dns323_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/* PCI-E */
+	if (dev->bus->number == orion_pcie_local_bus_nr())
+		return IRQ_ORION_PCIE0_INT;
+
+	pr_err("%s: requested mapping for unknown bus\n", __func__);
+
+	return -1;
+}
+
+static struct hw_pci dns323_pci __initdata = {
+	.nr_controllers = 1,
+	.swizzle	= pci_std_swizzle,
+	.setup		= orion_pci_sys_setup,
+	.scan		= orion_pci_sys_scan_bus,
+	.map_irq	= dns323_pci_map_irq,
+};
+
+static int __init dns323_pci_init(void)
+{
+	if (machine_is_dns323())
+		pci_common_init(&dns323_pci);
+
+	return 0;
+}
+
+subsys_initcall(dns323_pci_init);
+
+/****************************************************************************
+ * Ethernet
+ */
+
+static struct mv643xx_eth_platform_data dns323_eth_data = {
+	.phy_addr = 8,
+	.force_phy_addr = 1,
+};
+
+/****************************************************************************
+ * 8MiB NOR flash (Spansion S29GL064M90TFIR4)
+ *
+ * Layout as used by D-Link:
+ *  0x00000000-0x00010000 : "MTD1"
+ *  0x00010000-0x00020000 : "MTD2"
+ *  0x00020000-0x001a0000 : "Linux Kernel"
+ *  0x001a0000-0x007d0000 : "File System"
+ *  0x007d0000-0x00800000 : "u-boot"
+ */
+
+#define DNS323_NOR_BOOT_BASE 0xf4000000
+#define DNS323_NOR_BOOT_SIZE SZ_8M
+
+static struct mtd_partition dns323_partitions[] = {
+	{
+		.name	= "MTD1",
+		.size	= 0x00010000,
+		.offset	= 0,
+	}, {
+		.name	= "MTD2",
+		.size	= 0x00010000,
+		.offset = 0x00010000,
+	}, {
+		.name	= "Linux Kernel",
+		.size	= 0x00180000,
+		.offset	= 0x00020000,
+	}, {
+		.name	= "File System",
+		.size	= 0x00630000,
+		.offset	= 0x001A0000,
+	}, {
+		.name	= "u-boot",
+		.size	= 0x00030000,
+		.offset	= 0x007d0000,
+	}
+};
+
+static struct physmap_flash_data dns323_nor_flash_data = {
+	.width		= 1,
+	.parts		= dns323_partitions,
+	.nr_parts	= ARRAY_SIZE(dns323_partitions)
+};
+
+static struct resource dns323_nor_flash_resource = {
+	.flags		= IORESOURCE_MEM,
+	.start		= DNS323_NOR_BOOT_BASE,
+	.end		= DNS323_NOR_BOOT_BASE + DNS323_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device dns323_nor_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= { .platform_data = &dns323_nor_flash_data, },
+	.resource	= &dns323_nor_flash_resource,
+	.num_resources	= 1,
+};
+
+/****************************************************************************
+ * GPIO LEDs (simple - doesn't use hardware blinking support)
+ */
+
+static struct gpio_led dns323_leds[] = {
+	{
+		.name = "power:blue",
+		.gpio = DNS323_GPIO_LED_POWER,
+		.active_low = 1,
+	}, {
+		.name = "right:amber",
+		.gpio = DNS323_GPIO_LED_RIGHT_AMBER,
+		.active_low = 1,
+	}, {
+		.name = "left:amber",
+		.gpio = DNS323_GPIO_LED_LEFT_AMBER,
+		.active_low = 1,
+	},
+};
+
+static struct gpio_led_platform_data dns323_led_data = {
+	.num_leds	= ARRAY_SIZE(dns323_leds),
+	.leds		= dns323_leds,
+};
+
+static struct platform_device dns323_gpio_leds = {
+	.name		= "leds-gpio",
+	.id		= -1,
+	.dev		= { .platform_data = &dns323_led_data, },
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ */
+
+static struct gpio_keys_button dns323_buttons[] = {
+	{
+		.code		= KEY_RESTART,
+		.gpio		= DNS323_GPIO_KEY_RESET,
+		.desc		= "Reset Button",
+		.active_low	= 1,
+	},
+	{
+		.code		= KEY_POWER,
+		.gpio		= DNS323_GPIO_KEY_POWER,
+		.desc		= "Power Button",
+		.active_low	= 1,
+	}
+};
+
+static struct gpio_keys_platform_data dns323_button_data = {
+	.buttons	= dns323_buttons,
+	.nbuttons       = ARRAY_SIZE(dns323_buttons),
+};
+
+static struct platform_device dns323_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= { .platform_data  = &dns323_button_data, },
+};
+
+/****************************************************************************
+ * General Setup
+ */
+
+static struct platform_device *dns323_plat_devices[] __initdata = {
+	&dns323_nor_flash,
+	&dns323_gpio_leds,
+	&dns323_button_device,
+};
+
+/*
+ * On the DNS-323 the following devices are attached via I2C:
+ *
+ *  i2c addr | chip        | description
+ *  0x3e     | GMT G760Af  | fan speed PWM controller
+ *  0x48     | GMT G751-2f | temp. sensor and therm. watchdog (LM75 compatible)
+ *  0x68     | ST M41T80   | RTC w/ alarm
+ */
+static struct i2c_board_info __initdata dns323_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("g760a", 0x3e),
+		.type = "g760a",
+	},
+#if 0
+	/* this entry requires the new-style driver model lm75 driver,
+	 * for the meantime "insmod lm75.ko force_lm75=0,0x48" is needed */
+	{
+		I2C_BOARD_INFO("lm75", 0x48),
+		.type = "g751",
+	},
+#endif
+	{
+		I2C_BOARD_INFO("rtc-m41t80", 0x68),
+		.type = "m41t80",
+	}
+};
+
+/* DNS-323 specific power off method */
+static void dns323_power_off(void)
+{
+	pr_info("%s: triggering power-off...\n", __func__);
+	gpio_set_value(DNS323_GPIO_POWER_OFF, 1);
+}
+
+static void __init dns323_init(void)
+{
+	/* Setup basic Orion functions. Need to be called early. */
+	orion_init();
+
+	/* setup flash mapping
+	 * CS3 holds a 8 MB Spansion S29GL064M90TFIR4
+	 */
+	orion_setup_cpu_win(ORION_DEV_BOOT, DNS323_NOR_BOOT_BASE,
+			    DNS323_NOR_BOOT_SIZE, -1);
+
+	/* DNS-323 has a Marvell 88X7042 SATA controller attached via PCIE
+	 *
+	 * Open a special address decode windows for the PCIE WA.
+	 */
+	orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE);
+	orion_write(ORION_REGS_BASE | 0x20070,
+		    (0x7941 | (((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16));
+
+	/* set MPP to 0 as D-Link's 2.6.12.6 kernel did */
+	orion_write(MPP_0_7_CTRL, 0);
+	orion_write(MPP_8_15_CTRL, 0);
+	orion_write(MPP_16_19_CTRL, 0);
+	orion_write(MPP_DEV_CTRL, 0);
+
+	/* Define used GPIO pins
+
+	  GPIO Map:
+
+	  |  0 |     | PEX_RST_OUT (not controlled by GPIO)
+	  |  1 | Out | right amber LED (= sata ch0 LED)  (low-active)
+	  |  2 | Out | left  amber LED (= sata ch1 LED)  (low-active)
+	  |  3 | Out | //unknown//
+	  |  4 | Out | power button LED (low-active, together with pin #5)
+	  |  5 | Out | power button LED (low-active, together with pin #4)
+	  |  6 | In  | GMT G751-2f overtemp. shutdown signal (low-active)
+	  |  7 | In  | M41T80 nIRQ/OUT/SQW signal
+	  |  8 | Out | triggers power off (high-active)
+	  |  9 | In  | power button switch (low-active)
+	  | 10 | In  | reset button switch (low-active)
+	  | 11 | Out | //unknown//
+	  | 12 | Out | //unknown//
+	  | 13 | Out | //unknown//
+	  | 14 | Out | //unknown//
+	  | 15 | Out | //unknown//
+	*/
+	orion_gpio_set_valid_pins(0x07f6);
+
+	/* register dns323 specific power-off method */
+	if ((gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0)
+	    || (gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0))
+		pr_err("DNS323: failed to setup power-off GPIO\n");
+
+	pm_power_off = dns323_power_off;
+
+	/* register flash and other platform devices */
+	platform_add_devices(dns323_plat_devices,
+			     ARRAY_SIZE(dns323_plat_devices));
+
+	i2c_register_board_info(0, dns323_i2c_devices,
+				ARRAY_SIZE(dns323_i2c_devices));
+
+	orion_eth_init(&dns323_eth_data);
+}
+
+/* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */
+MACHINE_START(DNS323, "D-Link DNS-323")
+	/* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
+	.phys_io	= ORION_REGS_BASE,
+	.io_pg_offst	= ((ORION_REGS_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= dns323_init,
+	.map_io		= orion_map_io,
+	.init_irq	= orion_init_irq,
+	.timer		= &orion_timer,
+MACHINE_END
diff --git a/arch/arm/mach-orion/gpio.c b/arch/arm/mach-orion/gpio.c
new file mode 100644
index 0000000..d5f00c8
--- /dev/null
+++ b/arch/arm/mach-orion/gpio.c
@@ -0,0 +1,225 @@
+/*
+ * arch/arm/mach-orion/gpio.c
+ *
+ * GPIO functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+#include <asm/gpio.h>
+#include <asm/arch/orion.h>
+#include "common.h"
+
+static DEFINE_SPINLOCK(gpio_lock);
+static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)];
+static const char *gpio_label[GPIO_MAX];  /* non null for allocated GPIOs */
+
+void __init orion_gpio_set_valid_pins(u32 pins)
+{
+	gpio_valid[0] = pins;
+}
+
+/*
+ * GENERIC_GPIO primitives
+ */
+int gpio_direction_input(unsigned pin)
+{
+	unsigned long flags;
+
+	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+		pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	/*
+	 * Some callers might have not used the gpio_request(),
+	 * so flag this pin as requested now.
+	 */
+	if (!gpio_label[pin])
+		gpio_label[pin] = "?";
+
+	orion_setbits(GPIO_IO_CONF, 1 << pin);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned pin, int value)
+{
+	unsigned long flags;
+	int mask;
+
+	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+		pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	/*
+	 * Some callers might have not used the gpio_request(),
+	 * so flag this pin as requested now.
+	 */
+	if (!gpio_label[pin])
+		gpio_label[pin] = "?";
+
+	mask = 1 << pin;
+	orion_clrbits(GPIO_BLINK_EN, mask);
+	if (value)
+		orion_setbits(GPIO_OUT, mask);
+	else
+		orion_clrbits(GPIO_OUT, mask);
+	orion_clrbits(GPIO_IO_CONF, mask);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+int gpio_get_value(unsigned pin)
+{
+	int val, mask = 1 << pin;
+
+	if (orion_read(GPIO_IO_CONF) & mask)
+		val = orion_read(GPIO_DATA_IN) ^ orion_read(GPIO_IN_POL);
+	else
+		val = orion_read(GPIO_OUT);
+
+	return val & mask;
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+void gpio_set_value(unsigned pin, int value)
+{
+	unsigned long flags;
+	int mask = 1 << pin;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	orion_clrbits(GPIO_BLINK_EN, mask);
+	if (value)
+		orion_setbits(GPIO_OUT, mask);
+	else
+		orion_clrbits(GPIO_OUT, mask);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+void orion_gpio_set_blink(unsigned pin, int blink)
+{
+	unsigned long flags;
+	int mask = 1 << pin;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	orion_clrbits(GPIO_OUT, mask);
+	if (blink)
+		orion_setbits(GPIO_BLINK_EN, mask);
+	else
+		orion_clrbits(GPIO_BLINK_EN, mask);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+}
+EXPORT_SYMBOL(orion_gpio_set_blink);
+
+int gpio_request(unsigned pin, const char *label)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+		pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	if (gpio_label[pin]) {
+		pr_debug("%s: GPIO %d already used as %s\n",
+			 __FUNCTION__, pin, gpio_label[pin]);
+		ret = -EBUSY;
+	} else
+		gpio_label[pin] = label ? label : "?";
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(gpio_request);
+
+void gpio_free(unsigned pin)
+{
+	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+		pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin);
+		return;
+	}
+
+	if (!gpio_label[pin])
+		pr_warning("%s: GPIO %d already freed\n", __FUNCTION__, pin);
+	else
+		gpio_label[pin] = NULL;
+}
+EXPORT_SYMBOL(gpio_free);
+
+/* Debug helper */
+void gpio_display(void)
+{
+	int i;
+
+	for (i = 0; i < GPIO_MAX; i++) {
+		printk(KERN_DEBUG "Pin-%d: ", i);
+
+		if (!test_bit(i, gpio_valid)) {
+			printk("non-GPIO\n");
+		} else if (!gpio_label[i]) {
+			printk("GPIO, free\n");
+		} else {
+			printk("GPIO, used by %s, ", gpio_label[i]);
+			if (orion_read(GPIO_IO_CONF) & (1 << i)) {
+				printk("input, active %s, level %s, edge %s\n",
+				((orion_read(GPIO_IN_POL) >> i) & 1) ? "low" : "high",
+				((orion_read(GPIO_LEVEL_MASK) >> i) & 1) ? "enabled" : "masked",
+				((orion_read(GPIO_EDGE_MASK) >> i) & 1) ? "enabled" : "masked");
+			} else {
+				printk("output, val=%d\n", (orion_read(GPIO_OUT) >> i) & 1);
+			}
+		}
+	}
+
+	printk(KERN_DEBUG "MPP_0_7_CTRL (0x%08x) = 0x%08x\n",
+				MPP_0_7_CTRL, orion_read(MPP_0_7_CTRL));
+	printk(KERN_DEBUG "MPP_8_15_CTRL (0x%08x) = 0x%08x\n",
+				MPP_8_15_CTRL, orion_read(MPP_8_15_CTRL));
+	printk(KERN_DEBUG "MPP_16_19_CTRL (0x%08x) = 0x%08x\n",
+				MPP_16_19_CTRL, orion_read(MPP_16_19_CTRL));
+	printk(KERN_DEBUG "MPP_DEV_CTRL (0x%08x) = 0x%08x\n",
+				MPP_DEV_CTRL, orion_read(MPP_DEV_CTRL));
+	printk(KERN_DEBUG "GPIO_OUT (0x%08x) = 0x%08x\n",
+				GPIO_OUT, orion_read(GPIO_OUT));
+	printk(KERN_DEBUG "GPIO_IO_CONF (0x%08x) = 0x%08x\n",
+				GPIO_IO_CONF, orion_read(GPIO_IO_CONF));
+	printk(KERN_DEBUG "GPIO_BLINK_EN (0x%08x) = 0x%08x\n",
+				GPIO_BLINK_EN, orion_read(GPIO_BLINK_EN));
+	printk(KERN_DEBUG "GPIO_IN_POL (0x%08x) = 0x%08x\n",
+				GPIO_IN_POL, orion_read(GPIO_IN_POL));
+	printk(KERN_DEBUG "GPIO_DATA_IN (0x%08x) = 0x%08x\n",
+				GPIO_DATA_IN, orion_read(GPIO_DATA_IN));
+	printk(KERN_DEBUG "GPIO_LEVEL_MASK (0x%08x) = 0x%08x\n",
+				GPIO_LEVEL_MASK, orion_read(GPIO_LEVEL_MASK));
+	printk(KERN_DEBUG "GPIO_EDGE_CAUSE (0x%08x) = 0x%08x\n",
+				GPIO_EDGE_CAUSE, orion_read(GPIO_EDGE_CAUSE));
+	printk(KERN_DEBUG "GPIO_EDGE_MASK (0x%08x) = 0x%08x\n",
+				GPIO_EDGE_MASK, orion_read(GPIO_EDGE_MASK));
+}
diff --git a/arch/arm/mach-orion/irq.c b/arch/arm/mach-orion/irq.c
new file mode 100644
index 0000000..df7e12a
--- /dev/null
+++ b/arch/arm/mach-orion/irq.c
@@ -0,0 +1,241 @@
+/*
+ * arch/arm/mach-orion/irq.c
+ *
+ * Core IRQ functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/gpio.h>
+#include <asm/arch/orion.h>
+#include "common.h"
+
+/*****************************************************************************
+ * Orion GPIO IRQ
+ *
+ * GPIO_IN_POL register controlls whether GPIO_DATA_IN will hold the same
+ * value of the line or the opposite value.
+ *
+ * Level IRQ handlers: DATA_IN is used directly as cause register.
+ *                     Interrupt are masked by LEVEL_MASK registers.
+ * Edge IRQ handlers:  Change in DATA_IN are latched in EDGE_CAUSE.
+ *                     Interrupt are masked by EDGE_MASK registers.
+ * Both-edge handlers: Similar to regular Edge handlers, but also swaps
+ *                     the polarity to catch the next line transaction.
+ *                     This is a race condition that might not perfectly
+ *                     work on some use cases.
+ *
+ * Every eight GPIO lines are grouped (OR'ed) before going up to main
+ * cause register.
+ *
+ *                    EDGE  cause    mask
+ *        data-in   /--------| |-----| |----\
+ *     -----| |-----                         ---- to main cause reg
+ *           X      \----------------| |----/
+ *        polarity    LEVEL          mask
+ *
+ ****************************************************************************/
+static void orion_gpio_irq_ack(u32 irq)
+{
+	int pin = irq_to_gpio(irq);
+	if (irq_desc[irq].status & IRQ_LEVEL)
+		/*
+		 * Mask bit for level interrupt
+		 */
+		orion_clrbits(GPIO_LEVEL_MASK, 1 << pin);
+	else
+		/*
+		 * Clear casue bit for egde interrupt
+		 */
+		orion_clrbits(GPIO_EDGE_CAUSE, 1 << pin);
+}
+
+static void orion_gpio_irq_mask(u32 irq)
+{
+	int pin = irq_to_gpio(irq);
+	if (irq_desc[irq].status & IRQ_LEVEL)
+		orion_clrbits(GPIO_LEVEL_MASK, 1 << pin);
+	else
+		orion_clrbits(GPIO_EDGE_MASK, 1 << pin);
+}
+
+static void orion_gpio_irq_unmask(u32 irq)
+{
+	int pin = irq_to_gpio(irq);
+	if (irq_desc[irq].status & IRQ_LEVEL)
+		orion_setbits(GPIO_LEVEL_MASK, 1 << pin);
+	else
+		orion_setbits(GPIO_EDGE_MASK, 1 << pin);
+}
+
+static int orion_gpio_set_irq_type(u32 irq, u32 type)
+{
+	int pin = irq_to_gpio(irq);
+	struct irq_desc *desc;
+
+	if ((orion_read(GPIO_IO_CONF) & (1 << pin)) == 0) {
+		printk(KERN_ERR "orion_gpio_set_irq_type failed "
+				"(irq %d, pin %d).\n", irq, pin);
+		return -EINVAL;
+	}
+
+	desc = irq_desc + irq;
+
+	switch (type) {
+	case IRQT_HIGH:
+		desc->handle_irq = handle_level_irq;
+		desc->status |= IRQ_LEVEL;
+		orion_clrbits(GPIO_IN_POL, (1 << pin));
+		break;
+	case IRQT_LOW:
+		desc->handle_irq = handle_level_irq;
+		desc->status |= IRQ_LEVEL;
+		orion_setbits(GPIO_IN_POL, (1 << pin));
+		break;
+	case IRQT_RISING:
+		desc->handle_irq = handle_edge_irq;
+		desc->status &= ~IRQ_LEVEL;
+		orion_clrbits(GPIO_IN_POL, (1 << pin));
+		break;
+	case IRQT_FALLING:
+		desc->handle_irq = handle_edge_irq;
+		desc->status &= ~IRQ_LEVEL;
+		orion_setbits(GPIO_IN_POL, (1 << pin));
+		break;
+	case IRQT_BOTHEDGE:
+		desc->handle_irq = handle_edge_irq;
+		desc->status &= ~IRQ_LEVEL;
+		/*
+		 * set initial polarity based on current input level
+		 */
+		if ((orion_read(GPIO_IN_POL) ^ orion_read(GPIO_DATA_IN))
+		    & (1 << pin))
+			orion_setbits(GPIO_IN_POL, (1 << pin)); /* falling */
+		else
+			orion_clrbits(GPIO_IN_POL, (1 << pin)); /* rising */
+
+		break;
+	default:
+		printk(KERN_ERR "failed to set irq=%d (type=%d)\n", irq, type);
+		return -EINVAL;
+	}
+
+	desc->status &= ~IRQ_TYPE_SENSE_MASK;
+	desc->status |= type & IRQ_TYPE_SENSE_MASK;
+
+	return 0;
+}
+
+static struct irq_chip orion_gpio_irq_chip = {
+	.name		= "Orion-IRQ-GPIO",
+	.ack		= orion_gpio_irq_ack,
+	.mask		= orion_gpio_irq_mask,
+	.unmask		= orion_gpio_irq_unmask,
+	.set_type	= orion_gpio_set_irq_type,
+};
+
+static void orion_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	u32 cause, offs, pin;
+
+	BUG_ON(irq < IRQ_ORION_GPIO_0_7 || irq > IRQ_ORION_GPIO_24_31);
+	offs = (irq - IRQ_ORION_GPIO_0_7) * 8;
+	cause = (orion_read(GPIO_DATA_IN) & orion_read(GPIO_LEVEL_MASK)) |
+		(orion_read(GPIO_EDGE_CAUSE) & orion_read(GPIO_EDGE_MASK));
+
+	for (pin = offs; pin < offs + 8; pin++) {
+		if (cause & (1 << pin)) {
+			irq = gpio_to_irq(pin);
+			desc = irq_desc + irq;
+			if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) {
+				/* Swap polarity (race with GPIO line) */
+				u32 polarity = orion_read(GPIO_IN_POL);
+				polarity ^= 1 << pin;
+				orion_write(GPIO_IN_POL, polarity);
+			}
+			desc_handle_irq(irq, desc);
+		}
+	}
+}
+
+static void __init orion_init_gpio_irq(void)
+{
+	int i;
+	struct irq_desc *desc;
+
+	/*
+	 * Mask and clear GPIO IRQ interrupts
+	 */
+	orion_write(GPIO_LEVEL_MASK, 0x0);
+	orion_write(GPIO_EDGE_MASK, 0x0);
+	orion_write(GPIO_EDGE_CAUSE, 0x0);
+
+	/*
+	 * Register chained level handlers for GPIO IRQs by default.
+	 * User can use set_type() if he wants to use edge types handlers.
+	 */
+	for (i = IRQ_ORION_GPIO_START; i < NR_IRQS; i++) {
+		set_irq_chip(i, &orion_gpio_irq_chip);
+		set_irq_handler(i, handle_level_irq);
+		desc = irq_desc + i;
+		desc->status |= IRQ_LEVEL;
+		set_irq_flags(i, IRQF_VALID);
+	}
+	set_irq_chained_handler(IRQ_ORION_GPIO_0_7, orion_gpio_irq_handler);
+	set_irq_chained_handler(IRQ_ORION_GPIO_8_15, orion_gpio_irq_handler);
+	set_irq_chained_handler(IRQ_ORION_GPIO_16_23, orion_gpio_irq_handler);
+	set_irq_chained_handler(IRQ_ORION_GPIO_24_31, orion_gpio_irq_handler);
+}
+
+/*****************************************************************************
+ * Orion Main IRQ
+ ****************************************************************************/
+static void orion_main_irq_mask(u32 irq)
+{
+	orion_clrbits(MAIN_IRQ_MASK, 1 << irq);
+}
+
+static void orion_main_irq_unmask(u32 irq)
+{
+	orion_setbits(MAIN_IRQ_MASK, 1 << irq);
+}
+
+static struct irq_chip orion_main_irq_chip = {
+	.name		= "Orion-IRQ-Main",
+	.ack		= orion_main_irq_mask,
+	.mask		= orion_main_irq_mask,
+	.unmask		= orion_main_irq_unmask,
+};
+
+static void __init orion_init_main_irq(void)
+{
+	int i;
+
+	/*
+	 * Mask and clear Main IRQ interrupts
+	 */
+	orion_write(MAIN_IRQ_MASK, 0x0);
+	orion_write(MAIN_IRQ_CAUSE, 0x0);
+
+	/*
+	 * Register level handler for Main IRQs
+	 */
+	for (i = 0; i < IRQ_ORION_GPIO_START; i++) {
+		set_irq_chip(i, &orion_main_irq_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+}
+
+void __init orion_init_irq(void)
+{
+	orion_init_main_irq();
+	orion_init_gpio_irq();
+}
diff --git a/arch/arm/mach-orion/kurobox_pro-setup.c b/arch/arm/mach-orion/kurobox_pro-setup.c
new file mode 100644
index 0000000..2d812ed
--- /dev/null
+++ b/arch/arm/mach-orion/kurobox_pro-setup.c
@@ -0,0 +1,234 @@
+/*
+ * arch/arm/mach-orion/kurobox_pro-setup.c
+ *
+ * Maintainer: Ronen Shitrit <rshitrit@marvell.com>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/orion.h>
+#include <asm/arch/platform.h>
+#include "common.h"
+
+/*****************************************************************************
+ * KUROBOX-PRO Info
+ ****************************************************************************/
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define KUROBOX_PRO_NOR_BOOT_BASE	0xf4000000
+#define KUROBOX_PRO_NOR_BOOT_SIZE	SZ_256K
+
+/*
+ * 256M NAND flash on Device bus chip select 1
+ */
+
+#define KUROBOX_PRO_NAND_BASE		0xfc000000
+#define KUROBOX_PRO_NAND_SIZE		SZ_2M
+
+/*****************************************************************************
+ * 256MB NAND Flash on Device bus CS0
+ ****************************************************************************/
+
+static struct mtd_partition kurobox_pro_nand_parts[] = {
+	{
+		.name	= "uImage",
+		.offset	= 0,
+		.size	= SZ_4M,
+	},
+	{
+		.name	= "rootfs",
+		.offset	= SZ_4M,
+		.size	= SZ_64M,
+	},
+	{
+		.name	= "extra",
+		.offset	= SZ_4M + SZ_64M,
+		.size	= SZ_256M - (SZ_4M + SZ_64M),
+	},
+};
+
+static struct resource kurobox_pro_nand_resource = {
+	.flags		= IORESOURCE_MEM,
+	.start		= KUROBOX_PRO_NAND_BASE,
+	.end		= KUROBOX_PRO_NAND_BASE + KUROBOX_PRO_NAND_SIZE - 1,
+};
+
+static struct orion_nand_data kurobox_pro_nand_data = {
+	.parts		= kurobox_pro_nand_parts,
+	.nr_parts	= ARRAY_SIZE(kurobox_pro_nand_parts),
+	.cle		= 0,
+	.ale		= 1,
+	.width		= 8,
+};
+
+static struct platform_device kurobox_pro_nand_flash = {
+	.name		= "orion_nand",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &kurobox_pro_nand_data,
+	},
+	.resource	= &kurobox_pro_nand_resource,
+	.num_resources	= 1,
+};
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data kurobox_pro_nor_flash_data = {
+	.width		= 1,
+};
+
+static struct resource kurobox_pro_nor_flash_resource = {
+	.flags			= IORESOURCE_MEM,
+	.start			= KUROBOX_PRO_NOR_BOOT_BASE,
+	.end			= KUROBOX_PRO_NOR_BOOT_BASE + KUROBOX_PRO_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device kurobox_pro_nor_flash = {
+	.name			= "physmap-flash",
+	.id			= 0,
+	.dev		= {
+		.platform_data	= &kurobox_pro_nor_flash_data,
+	},
+	.num_resources		= 1,
+	.resource		= &kurobox_pro_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+static int __init kurobox_pro_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/*
+	 * PCI isn't used on the Kuro
+	 */
+	if (dev->bus->number == orion_pcie_local_bus_nr())
+		return IRQ_ORION_PCIE0_INT;
+	else
+		printk(KERN_ERR "kurobox_pro_pci_map_irq failed, unknown bus\n");
+
+	return -1;
+}
+
+static struct hw_pci kurobox_pro_pci __initdata = {
+	.nr_controllers	= 1,
+	.swizzle	= pci_std_swizzle,
+	.setup		= orion_pci_sys_setup,
+	.scan		= orion_pci_sys_scan_bus,
+	.map_irq	= kurobox_pro_pci_map_irq,
+};
+
+static int __init kurobox_pro_pci_init(void)
+{
+	if (machine_is_kurobox_pro())
+		pci_common_init(&kurobox_pro_pci);
+
+	return 0;
+}
+
+subsys_initcall(kurobox_pro_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data kurobox_pro_eth_data = {
+	.phy_addr	= 8,
+	.force_phy_addr = 1,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = {
+       .driver_name    = "rtc-rs5c372",
+       .type           = "rs5c372a",
+       .addr           = 0x32,
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static struct platform_device *kurobox_pro_devices[] __initdata = {
+	&kurobox_pro_nor_flash,
+	&kurobox_pro_nand_flash,
+};
+
+static void __init kurobox_pro_init(void)
+{
+	/*
+	 * Setup basic Orion functions. Need to be called early.
+	 */
+	orion_init();
+
+	/*
+	 * Setup the CPU address decode windows for our devices
+	 */
+	orion_setup_cpu_win(ORION_DEV_BOOT, KUROBOX_PRO_NOR_BOOT_BASE,
+				KUROBOX_PRO_NOR_BOOT_SIZE, -1);
+	orion_setup_cpu_win(ORION_DEV0,	KUROBOX_PRO_NAND_BASE,
+				KUROBOX_PRO_NAND_SIZE, -1);
+	/*
+	 * Open a special address decode windows for the PCIE WA.
+	 */
+	orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE);
+	orion_write(ORION_REGS_BASE | 0x20070, (0x7941 |
+		(((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16));
+
+	/*
+	 * Setup Multiplexing Pins --
+	 * MPP[0-1] Not used
+	 * MPP[2] GPIO Micon
+	 * MPP[3] GPIO RTC
+	 * MPP[4-5] Not used
+	 * MPP[6] Nand Flash REn
+	 * MPP[7] Nand Flash WEn
+	 * MPP[8-11] Not used
+	 * MPP[12] SATA 0 presence Indication
+	 * MPP[13] SATA 1 presence Indication
+	 * MPP[14] SATA 0 active Indication
+	 * MPP[15] SATA 1 active indication
+	 * MPP[16-19] Not used
+	 */
+	orion_write(MPP_0_7_CTRL, 0x44220003);
+	orion_write(MPP_8_15_CTRL, 0x55550000);
+	orion_write(MPP_16_19_CTRL, 0x0);
+
+	orion_gpio_set_valid_pins(0x0000000c);
+
+	platform_add_devices(kurobox_pro_devices, ARRAY_SIZE(kurobox_pro_devices));
+	i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1);
+	orion_eth_init(&kurobox_pro_eth_data);
+}
+
+MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro")
+	/* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
+	.phys_io	= ORION_REGS_BASE,
+	.io_pg_offst	= ((ORION_REGS_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= kurobox_pro_init,
+	.map_io		= orion_map_io,
+	.init_irq	= orion_init_irq,
+	.timer		= &orion_timer,
+MACHINE_END
diff --git a/arch/arm/mach-orion/pci.c b/arch/arm/mach-orion/pci.c
new file mode 100644
index 0000000..0498d7c
--- /dev/null
+++ b/arch/arm/mach-orion/pci.c
@@ -0,0 +1,557 @@
+/*
+ * arch/arm/mach-orion/pci.c
+ *
+ * PCI and PCIE functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/mach/pci.h>
+#include "common.h"
+
+/*****************************************************************************
+ * Orion has one PCIE controller and one PCI controller.
+ *
+ * Note1: The local PCIE bus number is '0'. The local PCI bus number
+ * follows the scanned PCIE bridged busses, if any.
+ *
+ * Note2: It is possible for PCI/PCIE agents to access many subsystem's
+ * space, by configuring BARs and Address Decode Windows, e.g. flashes on
+ * device bus, Orion registers, etc. However this code only enable the
+ * access to DDR banks.
+ ****************************************************************************/
+
+
+/*****************************************************************************
+ * PCIE controller
+ ****************************************************************************/
+#define PCIE_CTRL		ORION_PCIE_REG(0x1a00)
+#define PCIE_STAT		ORION_PCIE_REG(0x1a04)
+#define PCIE_DEV_ID		ORION_PCIE_REG(0x0000)
+#define PCIE_CMD_STAT		ORION_PCIE_REG(0x0004)
+#define PCIE_DEV_REV		ORION_PCIE_REG(0x0008)
+#define PCIE_MASK		ORION_PCIE_REG(0x1910)
+#define PCIE_CONF_ADDR		ORION_PCIE_REG(0x18f8)
+#define PCIE_CONF_DATA		ORION_PCIE_REG(0x18fc)
+
+/*
+ * PCIE_STAT bits
+ */
+#define PCIE_STAT_LINK_DOWN		1
+#define PCIE_STAT_BUS_OFFS		8
+#define PCIE_STAT_BUS_MASK		(0xff << PCIE_STAT_BUS_OFFS)
+#define PCIE_STAT_DEV_OFFS		20
+#define PCIE_STAT_DEV_MASK		(0x1f << PCIE_STAT_DEV_OFFS)
+
+/*
+ * PCIE_CONF_ADDR bits
+ */
+#define PCIE_CONF_REG(r)		((((r) & 0xf00) << 24) | ((r) & 0xfc))
+#define PCIE_CONF_FUNC(f)		(((f) & 0x3) << 8)
+#define PCIE_CONF_DEV(d)		(((d) & 0x1f) << 11)
+#define PCIE_CONF_BUS(b)		(((b) & 0xff) << 16)
+#define PCIE_CONF_ADDR_EN		(1 << 31)
+
+/*
+ * PCIE config cycles are done by programming the PCIE_CONF_ADDR register
+ * and then reading the PCIE_CONF_DATA register. Need to make sure these
+ * transactions are atomic.
+ */
+static DEFINE_SPINLOCK(orion_pcie_lock);
+
+void orion_pcie_id(u32 *dev, u32 *rev)
+{
+	*dev = orion_read(PCIE_DEV_ID) >> 16;
+	*rev = orion_read(PCIE_DEV_REV) & 0xff;
+}
+
+u32 orion_pcie_local_bus_nr(void)
+{
+	u32 stat = orion_read(PCIE_STAT);
+	return((stat & PCIE_STAT_BUS_MASK) >> PCIE_STAT_BUS_OFFS);
+}
+
+static u32 orion_pcie_local_dev_nr(void)
+{
+	u32 stat = orion_read(PCIE_STAT);
+	return((stat & PCIE_STAT_DEV_MASK) >> PCIE_STAT_DEV_OFFS);
+}
+
+static u32 orion_pcie_no_link(void)
+{
+	u32 stat = orion_read(PCIE_STAT);
+	return(stat & PCIE_STAT_LINK_DOWN);
+}
+
+static void orion_pcie_set_bus_nr(int nr)
+{
+	orion_clrbits(PCIE_STAT, PCIE_STAT_BUS_MASK);
+	orion_setbits(PCIE_STAT, nr << PCIE_STAT_BUS_OFFS);
+}
+
+static void orion_pcie_master_slave_enable(void)
+{
+	orion_setbits(PCIE_CMD_STAT, PCI_COMMAND_MASTER |
+					  PCI_COMMAND_IO |
+					  PCI_COMMAND_MEMORY);
+}
+
+static void orion_pcie_enable_interrupts(void)
+{
+	/*
+	 * Enable interrupts lines
+	 * INTA[24] INTB[25] INTC[26] INTD[27]
+	 */
+	orion_setbits(PCIE_MASK, 0xf<<24);
+}
+
+static int orion_pcie_valid_config(u32 bus, u32 dev)
+{
+	/*
+	 * Don't go out when trying to access --
+	 * 1. our own device
+	 * 2. where there's no device connected (no link)
+	 * 3. nonexisting devices on local bus
+	 */
+
+	if ((orion_pcie_local_bus_nr() == bus) &&
+	   (orion_pcie_local_dev_nr() == dev))
+		return 0;
+
+	if (orion_pcie_no_link())
+		return 0;
+
+	if (bus == orion_pcie_local_bus_nr())
+		if (((orion_pcie_local_dev_nr() == 0) && (dev != 1)) ||
+		   ((orion_pcie_local_dev_nr() != 0) && (dev != 0)))
+		return 0;
+
+	return 1;
+}
+
+static int orion_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+						int size, u32 *val)
+{
+	unsigned long flags;
+	unsigned int dev, rev, pcie_addr;
+
+	if (orion_pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	spin_lock_irqsave(&orion_pcie_lock, flags);
+
+	orion_write(PCIE_CONF_ADDR, PCIE_CONF_BUS(bus->number) |
+			PCIE_CONF_DEV(PCI_SLOT(devfn)) |
+			PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
+			PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN);
+
+	orion_pcie_id(&dev, &rev);
+	if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) {
+		/* extended register space */
+		pcie_addr = ORION_PCIE_WA_BASE;
+		pcie_addr |= PCIE_CONF_BUS(bus->number) |
+			PCIE_CONF_DEV(PCI_SLOT(devfn)) |
+			PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
+			PCIE_CONF_REG(where);
+		*val = orion_read(pcie_addr);
+	} else
+		*val = orion_read(PCIE_CONF_DATA);
+
+	if (size == 1)
+		*val = (*val >> (8*(where & 0x3))) & 0xff;
+	else if (size == 2)
+		*val = (*val >> (8*(where & 0x3))) & 0xffff;
+
+	spin_unlock_irqrestore(&orion_pcie_lock, flags);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int orion_pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where,
+						int size, u32 val)
+{
+	unsigned long flags;
+	int ret;
+
+	if (orion_pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	spin_lock_irqsave(&orion_pcie_lock, flags);
+
+	ret = PCIBIOS_SUCCESSFUL;
+
+	orion_write(PCIE_CONF_ADDR, PCIE_CONF_BUS(bus->number) |
+			PCIE_CONF_DEV(PCI_SLOT(devfn)) |
+			PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
+			PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN);
+
+	if (size == 4) {
+		__raw_writel(val, PCIE_CONF_DATA);
+	} else if (size == 2) {
+		__raw_writew(val, PCIE_CONF_DATA + (where & 0x3));
+	} else if (size == 1) {
+		__raw_writeb(val, PCIE_CONF_DATA + (where & 0x3));
+	} else {
+		ret = PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	spin_unlock_irqrestore(&orion_pcie_lock, flags);
+
+	return ret;
+}
+
+struct pci_ops orion_pcie_ops = {
+	.read = orion_pcie_rd_conf,
+	.write = orion_pcie_wr_conf,
+};
+
+
+static int orion_pcie_setup(struct pci_sys_data *sys)
+{
+	struct resource *res;
+
+	/*
+	 * Master + Slave enable
+	 */
+	orion_pcie_master_slave_enable();
+
+	/*
+	 * Enable interrupts lines A-D
+	 */
+	orion_pcie_enable_interrupts();
+
+	/*
+	 * Request resource
+	 */
+	res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
+	if (!res)
+		panic("orion_pci_setup unable to alloc resources");
+
+	/*
+	 * IORESOURCE_IO
+	 */
+	res[0].name = "PCI-EX I/O Space";
+	res[0].flags = IORESOURCE_IO;
+	res[0].start = ORION_PCIE_IO_REMAP;
+	res[0].end = res[0].start + ORION_PCIE_IO_SIZE - 1;
+	if (request_resource(&ioport_resource, &res[0]))
+		panic("Request PCIE IO resource failed\n");
+	sys->resource[0] = &res[0];
+
+	/*
+	 * IORESOURCE_MEM
+	 */
+	res[1].name = "PCI-EX Memory Space";
+	res[1].flags = IORESOURCE_MEM;
+	res[1].start = ORION_PCIE_MEM_BASE;
+	res[1].end = res[1].start + ORION_PCIE_MEM_SIZE - 1;
+	if (request_resource(&iomem_resource, &res[1]))
+		panic("Request PCIE Memory resource failed\n");
+	sys->resource[1] = &res[1];
+
+	sys->resource[2] = NULL;
+	sys->io_offset = 0;
+
+	return 1;
+}
+
+/*****************************************************************************
+ * PCI controller
+ ****************************************************************************/
+#define PCI_MODE		ORION_PCI_REG(0xd00)
+#define PCI_CMD			ORION_PCI_REG(0xc00)
+#define PCI_P2P_CONF		ORION_PCI_REG(0x1d14)
+#define PCI_CONF_ADDR		ORION_PCI_REG(0xc78)
+#define PCI_CONF_DATA		ORION_PCI_REG(0xc7c)
+
+/*
+ * PCI_MODE bits
+ */
+#define PCI_MODE_64BIT			(1 << 2)
+#define PCI_MODE_PCIX			((1 << 4) | (1 << 5))
+
+/*
+ * PCI_CMD bits
+ */
+#define PCI_CMD_HOST_REORDER		(1 << 29)
+
+/*
+ * PCI_P2P_CONF bits
+ */
+#define PCI_P2P_BUS_OFFS		16
+#define PCI_P2P_BUS_MASK		(0xff << PCI_P2P_BUS_OFFS)
+#define PCI_P2P_DEV_OFFS		24
+#define PCI_P2P_DEV_MASK		(0x1f << PCI_P2P_DEV_OFFS)
+
+/*
+ * PCI_CONF_ADDR bits
+ */
+#define PCI_CONF_REG(reg)		((reg) & 0xfc)
+#define PCI_CONF_FUNC(func)		(((func) & 0x3) << 8)
+#define PCI_CONF_DEV(dev)		(((dev) & 0x1f) << 11)
+#define PCI_CONF_BUS(bus)		(((bus) & 0xff) << 16)
+#define PCI_CONF_ADDR_EN		(1 << 31)
+
+/*
+ * Internal configuration space
+ */
+#define PCI_CONF_FUNC_STAT_CMD		0
+#define PCI_CONF_REG_STAT_CMD		4
+#define PCIX_STAT			0x64
+#define PCIX_STAT_BUS_OFFS		8
+#define PCIX_STAT_BUS_MASK		(0xff << PCIX_STAT_BUS_OFFS)
+
+/*
+ * PCI config cycles are done by programming the PCI_CONF_ADDR register
+ * and then reading the PCI_CONF_DATA register. Need to make sure these
+ * transactions are atomic.
+ */
+static DEFINE_SPINLOCK(orion_pci_lock);
+
+u32 orion_pci_local_bus_nr(void)
+{
+	u32 conf = orion_read(PCI_P2P_CONF);
+	return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS);
+}
+
+u32 orion_pci_local_dev_nr(void)
+{
+	u32 conf = orion_read(PCI_P2P_CONF);
+	return((conf & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS);
+}
+
+int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func,
+					u32 where, u32 size, u32 *val)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&orion_pci_lock, flags);
+
+	orion_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) |
+			PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
+			PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN);
+
+	*val = orion_read(PCI_CONF_DATA);
+
+	if (size == 1)
+		*val = (*val >> (8*(where & 0x3))) & 0xff;
+	else if (size == 2)
+		*val = (*val >> (8*(where & 0x3))) & 0xffff;
+
+	spin_unlock_irqrestore(&orion_pci_lock, flags);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func,
+					u32 where, u32 size, u32 val)
+{
+	unsigned long flags;
+	int ret = PCIBIOS_SUCCESSFUL;
+
+	spin_lock_irqsave(&orion_pci_lock, flags);
+
+	orion_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) |
+			PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
+			PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN);
+
+	if (size == 4) {
+		__raw_writel(val, PCI_CONF_DATA);
+	} else if (size == 2) {
+		__raw_writew(val, PCI_CONF_DATA + (where & 0x3));
+	} else if (size == 1) {
+		__raw_writeb(val, PCI_CONF_DATA + (where & 0x3));
+	} else {
+		ret = PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	spin_unlock_irqrestore(&orion_pci_lock, flags);
+
+	return ret;
+}
+
+static int orion_pci_rd_conf(struct pci_bus *bus, u32 devfn,
+				int where, int size, u32 *val)
+{
+	/*
+	 * Don't go out for local device
+	 */
+	if ((orion_pci_local_bus_nr() == bus->number) &&
+	   (orion_pci_local_dev_nr() == PCI_SLOT(devfn))) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	return orion_pci_hw_rd_conf(bus->number, PCI_SLOT(devfn),
+					PCI_FUNC(devfn), where, size, val);
+}
+
+static int orion_pci_wr_conf(struct pci_bus *bus, u32 devfn,
+				int where, int size, u32 val)
+{
+	/*
+	 * Don't go out for local device
+	 */
+	if ((orion_pci_local_bus_nr() == bus->number) &&
+	   (orion_pci_local_dev_nr() == PCI_SLOT(devfn)))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return orion_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn),
+					PCI_FUNC(devfn), where, size, val);
+}
+
+struct pci_ops orion_pci_ops = {
+	.read = orion_pci_rd_conf,
+	.write = orion_pci_wr_conf,
+};
+
+static void orion_pci_set_bus_nr(int nr)
+{
+	u32 p2p = orion_read(PCI_P2P_CONF);
+
+	if (orion_read(PCI_MODE) & PCI_MODE_PCIX) {
+		/*
+		 * PCI-X mode
+		 */
+		u32 pcix_status, bus, dev;
+		bus = (p2p & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS;
+		dev = (p2p & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS;
+		orion_pci_hw_rd_conf(bus, dev, 0, PCIX_STAT, 4, &pcix_status);
+		pcix_status &= ~PCIX_STAT_BUS_MASK;
+		pcix_status |= (nr << PCIX_STAT_BUS_OFFS);
+		orion_pci_hw_wr_conf(bus, dev, 0, PCIX_STAT, 4, pcix_status);
+	} else {
+		/*
+		 * PCI Conventional mode
+		 */
+		p2p &= ~PCI_P2P_BUS_MASK;
+		p2p |= (nr << PCI_P2P_BUS_OFFS);
+		orion_write(PCI_P2P_CONF, p2p);
+	}
+}
+
+static void orion_pci_master_slave_enable(void)
+{
+	u32 bus_nr, dev_nr, func, reg, val;
+
+	bus_nr = orion_pci_local_bus_nr();
+	dev_nr = orion_pci_local_dev_nr();
+	func = PCI_CONF_FUNC_STAT_CMD;
+	reg = PCI_CONF_REG_STAT_CMD;
+	orion_pci_hw_rd_conf(bus_nr, dev_nr, func, reg, 4, &val);
+	val |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+	orion_pci_hw_wr_conf(bus_nr, dev_nr, func, reg, 4, val | 0x7);
+}
+
+static int orion_pci_setup(struct pci_sys_data *sys)
+{
+	struct resource *res;
+
+	/*
+	 * Master + Slave enable
+	 */
+	orion_pci_master_slave_enable();
+
+	/*
+	 * Force ordering
+	 */
+	orion_setbits(PCI_CMD, PCI_CMD_HOST_REORDER);
+
+	/*
+	 * Request resources
+	 */
+	res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
+	if (!res)
+		panic("orion_pci_setup unable to alloc resources");
+
+	/*
+	 * IORESOURCE_IO
+	 */
+	res[0].name = "PCI I/O Space";
+	res[0].flags = IORESOURCE_IO;
+	res[0].start = ORION_PCI_IO_REMAP;
+	res[0].end = res[0].start + ORION_PCI_IO_SIZE - 1;
+	if (request_resource(&ioport_resource, &res[0]))
+		panic("Request PCI IO resource failed\n");
+	sys->resource[0] = &res[0];
+
+	/*
+	 * IORESOURCE_MEM
+	 */
+	res[1].name = "PCI Memory Space";
+	res[1].flags = IORESOURCE_MEM;
+	res[1].start = ORION_PCI_MEM_BASE;
+	res[1].end = res[1].start + ORION_PCI_MEM_SIZE - 1;
+	if (request_resource(&iomem_resource, &res[1]))
+		panic("Request PCI Memory resource failed\n");
+	sys->resource[1] = &res[1];
+
+	sys->resource[2] = NULL;
+	sys->io_offset = 0;
+
+	return 1;
+}
+
+
+/*****************************************************************************
+ * General PCIE + PCI
+ ****************************************************************************/
+int orion_pci_sys_setup(int nr, struct pci_sys_data *sys)
+{
+	int ret = 0;
+
+	if (nr == 0) {
+		/*
+		 * PCIE setup
+		 */
+		orion_pcie_set_bus_nr(0);
+		ret = orion_pcie_setup(sys);
+	} else if (nr == 1) {
+		/*
+		 * PCI setup
+		 */
+		ret = orion_pci_setup(sys);
+	}
+
+	return ret;
+}
+
+struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	struct pci_ops *ops;
+	struct pci_bus *bus;
+
+
+	if (nr == 0) {
+		u32 pci_bus;
+		/*
+		 * PCIE scan
+		 */
+		ops = &orion_pcie_ops;
+		bus = pci_scan_bus(sys->busnr, ops, sys);
+		/*
+		 * Set local PCI bus number to follow PCIE bridges (if any)
+		 */
+		pci_bus	= bus->number + bus->subordinate - bus->secondary + 1;
+		orion_pci_set_bus_nr(pci_bus);
+	} else if (nr == 1) {
+		/*
+		 * PCI scan
+		 */
+		ops = &orion_pci_ops;
+		bus = pci_scan_bus(sys->busnr, ops, sys);
+	} else {
+		BUG();
+		bus = NULL;
+	}
+
+	return bus;
+}
diff --git a/arch/arm/mach-orion/rd88f5182-setup.c b/arch/arm/mach-orion/rd88f5182-setup.c
new file mode 100644
index 0000000..026d743
--- /dev/null
+++ b/arch/arm/mach-orion/rd88f5182-setup.c
@@ -0,0 +1,306 @@
+/*
+ * arch/arm/mach-orion/rd88f5182-setup.c
+ *
+ * Marvell Orion-NAS Reference Design Setup
+ *
+ * Maintainer: Ronen Shitrit <rshitrit@marvell.com>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/leds.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/orion.h>
+#include <asm/arch/platform.h>
+#include "common.h"
+
+/*****************************************************************************
+ * RD-88F5182 Info
+ ****************************************************************************/
+
+/*
+ * 512K NOR flash Device bus boot chip select
+ */
+
+#define RD88F5182_NOR_BOOT_BASE		0xf4000000
+#define RD88F5182_NOR_BOOT_SIZE		SZ_512K
+
+/*
+ * 16M NOR flash on Device bus chip select 1
+ */
+
+#define RD88F5182_NOR_BASE		0xfc000000
+#define RD88F5182_NOR_SIZE		SZ_16M
+
+/*
+ * PCI
+ */
+
+#define RD88F5182_PCI_SLOT0_OFFS	7
+#define RD88F5182_PCI_SLOT0_IRQ_A_PIN	7
+#define RD88F5182_PCI_SLOT0_IRQ_B_PIN	6
+
+/*
+ * GPIO Debug LED
+ */
+
+#define RD88F5182_GPIO_DBG_LED		0
+
+/*****************************************************************************
+ * 16M NOR Flash on Device bus CS1
+ ****************************************************************************/
+
+static struct physmap_flash_data rd88f5182_nor_flash_data = {
+	.width		= 1,
+};
+
+static struct resource rd88f5182_nor_flash_resource = {
+	.flags			= IORESOURCE_MEM,
+	.start			= RD88F5182_NOR_BASE,
+	.end			= RD88F5182_NOR_BASE + RD88F5182_NOR_SIZE - 1,
+};
+
+static struct platform_device rd88f5182_nor_flash = {
+	.name			= "physmap-flash",
+	.id			= 0,
+	.dev		= {
+		.platform_data	= &rd88f5182_nor_flash_data,
+	},
+	.num_resources		= 1,
+	.resource		= &rd88f5182_nor_flash_resource,
+};
+
+#ifdef CONFIG_LEDS
+
+/*****************************************************************************
+ * Use GPIO debug led as CPU active indication
+ ****************************************************************************/
+
+static void rd88f5182_dbgled_event(led_event_t evt)
+{
+	int val;
+
+	if (evt == led_idle_end)
+		val = 1;
+	else if (evt == led_idle_start)
+		val = 0;
+	else
+		return;
+
+	gpio_set_value(RD88F5182_GPIO_DBG_LED, val);
+}
+
+static int __init rd88f5182_dbgled_init(void)
+{
+	int pin;
+
+	if (machine_is_rd88f5182()) {
+		pin = RD88F5182_GPIO_DBG_LED;
+
+		if (gpio_request(pin, "DBGLED") == 0) {
+			if (gpio_direction_output(pin, 0) != 0) {
+				printk(KERN_ERR "rd88f5182_dbgled_init failed "
+						"to set output pin %d\n", pin);
+				gpio_free(pin);
+				return 0;
+			}
+		} else {
+			printk(KERN_ERR "rd88f5182_dbgled_init failed "
+					"to request gpio %d\n", pin);
+			return 0;
+		}
+
+		leds_event = rd88f5182_dbgled_event;
+	}
+	return 0;
+}
+
+__initcall(rd88f5182_dbgled_init);
+
+#endif
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+void __init rd88f5182_pci_preinit(void)
+{
+	int pin;
+
+	/*
+	 * Configure PCI GPIO IRQ pins
+	 */
+	pin = RD88F5182_PCI_SLOT0_IRQ_A_PIN;
+	if (gpio_request(pin, "PCI IntA") == 0) {
+		if (gpio_direction_input(pin) == 0) {
+			set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+		} else {
+			printk(KERN_ERR "rd88f5182_pci_preinit faield to "
+					"set_irq_type pin %d\n", pin);
+			gpio_free(pin);
+		}
+	} else {
+		printk(KERN_ERR "rd88f5182_pci_preinit failed to request gpio %d\n", pin);
+	}
+
+	pin = RD88F5182_PCI_SLOT0_IRQ_B_PIN;
+	if (gpio_request(pin, "PCI IntB") == 0) {
+		if (gpio_direction_input(pin) == 0) {
+			set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+		} else {
+			printk(KERN_ERR "rd88f5182_pci_preinit faield to "
+					"set_irq_type pin %d\n", pin);
+			gpio_free(pin);
+		}
+	} else {
+		printk(KERN_ERR "rd88f5182_pci_preinit failed to gpio_request %d\n", pin);
+	}
+}
+
+static int __init rd88f5182_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/*
+	 * PCI-E isn't used on the RD2
+	 */
+	if (dev->bus->number == orion_pcie_local_bus_nr())
+		return IRQ_ORION_PCIE0_INT;
+
+	/*
+	 * PCI IRQs are connected via GPIOs
+	 */
+	switch (slot - RD88F5182_PCI_SLOT0_OFFS) {
+	case 0:
+		if (pin == 1)
+			return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_A_PIN);
+		else
+			return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_B_PIN);
+	default:
+		return -1;
+	}
+}
+
+static struct hw_pci rd88f5182_pci __initdata = {
+	.nr_controllers	= 2,
+	.preinit	= rd88f5182_pci_preinit,
+	.swizzle	= pci_std_swizzle,
+	.setup		= orion_pci_sys_setup,
+	.scan		= orion_pci_sys_scan_bus,
+	.map_irq	= rd88f5182_pci_map_irq,
+};
+
+static int __init rd88f5182_pci_init(void)
+{
+	if (machine_is_rd88f5182())
+		pci_common_init(&rd88f5182_pci);
+
+	return 0;
+}
+
+subsys_initcall(rd88f5182_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data rd88f5182_eth_data = {
+	.phy_addr	= 8,
+	.force_phy_addr = 1,
+};
+
+/*****************************************************************************
+ * RTC DS1338 on I2C bus
+ ****************************************************************************/
+static struct i2c_board_info __initdata rd88f5182_i2c_rtc = {
+	.driver_name	= "rtc-ds1307",
+	.type		= "ds1338",
+	.addr		= 0x68,
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static struct platform_device *rd88f5182_devices[] __initdata = {
+	&rd88f5182_nor_flash,
+};
+
+static void __init rd88f5182_init(void)
+{
+	/*
+	 * Setup basic Orion functions. Need to be called early.
+	 */
+	orion_init();
+
+	/*
+	 * Setup the CPU address decode windows for our devices
+	 */
+	orion_setup_cpu_win(ORION_DEV_BOOT, RD88F5182_NOR_BOOT_BASE,
+				RD88F5182_NOR_BOOT_SIZE, -1);
+	orion_setup_cpu_win(ORION_DEV1, RD88F5182_NOR_BASE,
+				RD88F5182_NOR_SIZE, -1);
+
+	/*
+	 * Open a special address decode windows for the PCIE WA.
+	 */
+	orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE);
+	orion_write(ORION_REGS_BASE | 0x20070, (0x7941 |
+		(((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16));
+
+	/*
+	 * Setup Multiplexing Pins --
+	 * MPP[0] Debug Led (GPIO - Out)
+	 * MPP[1] Debug Led (GPIO - Out)
+	 * MPP[2] N/A
+	 * MPP[3] RTC_Int (GPIO - In)
+	 * MPP[4] GPIO
+	 * MPP[5] GPIO
+	 * MPP[6] PCI_intA (GPIO - In)
+	 * MPP[7] PCI_intB (GPIO - In)
+	 * MPP[8-11] N/A
+	 * MPP[12] SATA 0 presence Indication
+	 * MPP[13] SATA 1 presence Indication
+	 * MPP[14] SATA 0 active Indication
+	 * MPP[15] SATA 1 active indication
+	 * MPP[16-19] Not used
+	 * MPP[20] PCI Clock to MV88F5182
+	 * MPP[21] PCI Clock to mini PCI CON11
+	 * MPP[22] USB 0 over current indication
+	 * MPP[23] USB 1 over current indication
+	 * MPP[24] USB 1 over current enable
+	 * MPP[25] USB 0 over current enable
+	 */
+
+	orion_write(MPP_0_7_CTRL, 0x00000003);
+	orion_write(MPP_8_15_CTRL, 0x55550000);
+	orion_write(MPP_16_19_CTRL, 0x5555);
+
+	orion_gpio_set_valid_pins(0x000000fb);
+
+	platform_add_devices(rd88f5182_devices, ARRAY_SIZE(rd88f5182_devices));
+	i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1);
+	orion_eth_init(&rd88f5182_eth_data);
+}
+
+MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design")
+	/* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
+	.phys_io	= ORION_REGS_BASE,
+	.io_pg_offst	= ((ORION_REGS_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= rd88f5182_init,
+	.map_io		= orion_map_io,
+	.init_irq	= orion_init_irq,
+	.timer		= &orion_timer,
+MACHINE_END
diff --git a/arch/arm/mach-orion/time.c b/arch/arm/mach-orion/time.c
new file mode 100644
index 0000000..bd4262d
--- /dev/null
+++ b/arch/arm/mach-orion/time.c
@@ -0,0 +1,181 @@
+/*
+ * arch/arm/mach-orion/time.c
+ *
+ * Core time functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/mach/time.h>
+#include <asm/arch/orion.h>
+#include "common.h"
+
+/*
+ * Timer0: clock_event_device, Tick.
+ * Timer1: clocksource, Free running.
+ * WatchDog: Not used.
+ *
+ * Timers are counting down.
+ */
+#define CLOCKEVENT	0
+#define CLOCKSOURCE	1
+
+/*
+ * Timers bits
+ */
+#define BRIDGE_INT_TIMER(x)	(1 << ((x) + 1))
+#define TIMER_EN(x)		(1 << ((x) * 2))
+#define TIMER_RELOAD_EN(x)	(1 << (((x) * 2) + 1))
+#define BRIDGE_INT_TIMER_WD	(1 << 3)
+#define TIMER_WD_EN		(1 << 4)
+#define TIMER_WD_RELOAD_EN	(1 << 5)
+
+static cycle_t orion_clksrc_read(void)
+{
+	return (0xffffffff - orion_read(TIMER_VAL(CLOCKSOURCE)));
+}
+
+static struct clocksource orion_clksrc = {
+	.name		= "orion_clocksource",
+	.shift		= 20,
+	.rating		= 300,
+	.read		= orion_clksrc_read,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int
+orion_clkevt_next_event(unsigned long delta, struct clock_event_device *dev)
+{
+	unsigned long flags;
+
+	if (delta == 0)
+		return -ETIME;
+
+	local_irq_save(flags);
+
+	/*
+	 * Clear and enable timer interrupt bit
+	 */
+	orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT));
+	orion_setbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT));
+
+	/*
+	 * Setup new timer value
+	 */
+	orion_write(TIMER_VAL(CLOCKEVENT), delta);
+
+	/*
+	 * Disable auto reload and kickoff the timer
+	 */
+	orion_clrbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT));
+	orion_setbits(TIMER_CTRL, TIMER_EN(CLOCKEVENT));
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static void
+orion_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	if (mode == CLOCK_EVT_MODE_PERIODIC) {
+		/*
+		 * Setup latch cycles in timer and enable reload interrupt.
+		 */
+		orion_write(TIMER_VAL_RELOAD(CLOCKEVENT), LATCH);
+		orion_write(TIMER_VAL(CLOCKEVENT), LATCH);
+		orion_setbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT));
+		orion_setbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT) |
+					  TIMER_EN(CLOCKEVENT));
+	} else {
+		/*
+		 * Disable timer and interrupt
+		 */
+		orion_clrbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT));
+		orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT));
+		orion_clrbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT) |
+					  TIMER_EN(CLOCKEVENT));
+	}
+
+	local_irq_restore(flags);
+}
+
+static struct clock_event_device orion_clkevt = {
+	.name		= "orion_tick",
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.shift		= 32,
+	.rating		= 300,
+	.cpumask	= CPU_MASK_CPU0,
+	.set_next_event	= orion_clkevt_next_event,
+	.set_mode	= orion_clkevt_mode,
+};
+
+static irqreturn_t orion_timer_interrupt(int irq, void *dev_id)
+{
+	/*
+	 * Clear cause bit and do event
+	 */
+	orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT));
+	orion_clkevt.event_handler(&orion_clkevt);
+	return IRQ_HANDLED;
+}
+
+static struct irqaction orion_timer_irq = {
+	.name		= "orion_tick",
+	.flags		= IRQF_DISABLED | IRQF_TIMER,
+	.handler	= orion_timer_interrupt
+};
+
+static void orion_timer_init(void)
+{
+	/*
+	 * Setup clocksource free running timer (no interrupt on reload)
+	 */
+	orion_write(TIMER_VAL(CLOCKSOURCE), 0xffffffff);
+	orion_write(TIMER_VAL_RELOAD(CLOCKSOURCE), 0xffffffff);
+	orion_clrbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKSOURCE));
+	orion_setbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKSOURCE) |
+				  TIMER_EN(CLOCKSOURCE));
+
+	/*
+	 * Register clocksource
+	 */
+	orion_clksrc.mult =
+		clocksource_hz2mult(CLOCK_TICK_RATE, orion_clksrc.shift);
+
+	clocksource_register(&orion_clksrc);
+
+	/*
+	 * Connect and enable tick handler
+	 */
+	setup_irq(IRQ_ORION_BRIDGE, &orion_timer_irq);
+
+	/*
+	 * Register clockevent
+	 */
+	orion_clkevt.mult =
+		div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, orion_clkevt.shift);
+	orion_clkevt.max_delta_ns =
+		clockevent_delta2ns(0xfffffffe, &orion_clkevt);
+	orion_clkevt.min_delta_ns =
+		clockevent_delta2ns(1, &orion_clkevt);
+
+	clockevents_register_device(&orion_clkevt);
+}
+
+struct sys_timer orion_timer = {
+	.init = orion_timer_init,
+};
diff --git a/arch/arm/mach-orion/ts209-setup.c b/arch/arm/mach-orion/ts209-setup.c
new file mode 100644
index 0000000..e3e930e
--- /dev/null
+++ b/arch/arm/mach-orion/ts209-setup.c
@@ -0,0 +1,335 @@
+/*
+ * QNAP TS-109/TS-209 Board Setup
+ *
+ * Maintainer: Byron Bradley <byron.bbradley@gmail.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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/serial_reg.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/orion.h>
+#include <asm/arch/platform.h>
+#include "common.h"
+
+#define QNAP_TS209_NOR_BOOT_BASE 0xf4000000
+#define QNAP_TS209_NOR_BOOT_SIZE SZ_8M
+
+/****************************************************************************
+ * 8MiB NOR flash. The struct mtd_partition is not in the same order as the
+ *     partitions on the device because we want to keep compatability with
+ *     existing QNAP firmware.
+ *
+ * Layout as used by QNAP:
+ *  [2] 0x00000000-0x00200000 : "Kernel"
+ *  [3] 0x00200000-0x00600000 : "RootFS1"
+ *  [4] 0x00600000-0x00700000 : "RootFS2"
+ *  [6] 0x00700000-0x00760000 : "NAS Config" (read-only)
+ *  [5] 0x00760000-0x00780000 : "U-Boot Config"
+ *  [1] 0x00780000-0x00800000 : "U-Boot" (read-only)
+ ***************************************************************************/
+static struct mtd_partition qnap_ts209_partitions[] = {
+	{
+		.name       = "U-Boot",
+		.size       = 0x00080000,
+		.offset     = 0x00780000,
+		.mask_flags = MTD_WRITEABLE,
+	}, {
+		.name   = "Kernel",
+		.size   = 0x00200000,
+		.offset = 0,
+	}, {
+		.name   = "RootFS1",
+		.size   = 0x00400000,
+		.offset = 0x00200000,
+	}, {
+		.name   = "RootFS2",
+		.size   = 0x00100000,
+		.offset = 0x00600000,
+	}, {
+		.name   = "U-Boot Config",
+		.size   = 0x00020000,
+		.offset = 0x00760000,
+	}, {
+		.name       = "NAS Config",
+		.size       = 0x00060000,
+		.offset     = 0x00700000,
+		.mask_flags = MTD_WRITEABLE,
+	}
+};
+
+static struct physmap_flash_data qnap_ts209_nor_flash_data = {
+	.width    = 1,
+	.parts    = qnap_ts209_partitions,
+	.nr_parts = ARRAY_SIZE(qnap_ts209_partitions)
+};
+
+static struct resource qnap_ts209_nor_flash_resource = {
+	.flags = IORESOURCE_MEM,
+	.start = QNAP_TS209_NOR_BOOT_BASE,
+	.end   = QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device qnap_ts209_nor_flash = {
+	.name          = "physmap-flash",
+	.id            = 0,
+	.dev           = { .platform_data = &qnap_ts209_nor_flash_data, },
+	.resource      = &qnap_ts209_nor_flash_resource,
+	.num_resources = 1,
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+#define QNAP_TS209_PCI_SLOT0_OFFS	7
+#define QNAP_TS209_PCI_SLOT0_IRQ_PIN	6
+#define QNAP_TS209_PCI_SLOT1_IRQ_PIN	7
+
+void __init qnap_ts209_pci_preinit(void)
+{
+	int pin;
+
+	/*
+	 * Configure PCI GPIO IRQ pins
+	 */
+	pin = QNAP_TS209_PCI_SLOT0_IRQ_PIN;
+	if (gpio_request(pin, "PCI Int1") == 0) {
+		if (gpio_direction_input(pin) == 0) {
+			set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+		} else {
+			printk(KERN_ERR "qnap_ts209_pci_preinit failed to "
+					"set_irq_type pin %d\n", pin);
+			gpio_free(pin);
+		}
+	} else {
+		printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request "
+				"%d\n", pin);
+	}
+
+	pin = QNAP_TS209_PCI_SLOT1_IRQ_PIN;
+	if (gpio_request(pin, "PCI Int2") == 0) {
+		if (gpio_direction_input(pin) == 0) {
+			set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+		} else {
+			printk(KERN_ERR "qnap_ts209_pci_preinit failed "
+					"to set_irq_type pin %d\n", pin);
+			gpio_free(pin);
+		}
+	} else {
+		printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request "
+				"%d\n", pin);
+	}
+}
+
+static int __init qnap_ts209_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/*
+	 * PCIE IRQ is connected internally (not GPIO)
+	 */
+	if (dev->bus->number == orion_pcie_local_bus_nr())
+		return IRQ_ORION_PCIE0_INT;
+
+	/*
+	 * PCI IRQs are connected via GPIOs
+	 */
+	switch (slot - QNAP_TS209_PCI_SLOT0_OFFS) {
+	case 0:
+		return gpio_to_irq(QNAP_TS209_PCI_SLOT0_IRQ_PIN);
+	case 1:
+		return gpio_to_irq(QNAP_TS209_PCI_SLOT1_IRQ_PIN);
+	default:
+		return -1;
+	}
+}
+
+static struct hw_pci qnap_ts209_pci __initdata = {
+	.nr_controllers = 2,
+	.preinit        = qnap_ts209_pci_preinit,
+	.swizzle        = pci_std_swizzle,
+	.setup          = orion_pci_sys_setup,
+	.scan           = orion_pci_sys_scan_bus,
+	.map_irq        = qnap_ts209_pci_map_irq,
+};
+
+static int __init qnap_ts209_pci_init(void)
+{
+	if (machine_is_ts_x09())
+		pci_common_init(&qnap_ts209_pci);
+
+	return 0;
+}
+
+subsys_initcall(qnap_ts209_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data qnap_ts209_eth_data = {
+	.phy_addr       = 8,
+	.force_phy_addr = 1,
+};
+
+/*****************************************************************************
+ * RTC S35390A on I2C bus
+ ****************************************************************************/
+static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = {
+       .driver_name = "rtc-s35390a",
+       .addr        = 0x30,
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ *     Power button is attached to the PIC microcontroller
+ ****************************************************************************/
+
+#define QNAP_TS209_GPIO_KEY_MEDIA	1
+#define QNAP_TS209_GPIO_KEY_RESET	2
+
+static struct gpio_keys_button qnap_ts209_buttons[] = {
+	{
+		.code		= KEY_RESTART,
+		.gpio		= QNAP_TS209_GPIO_KEY_MEDIA,
+		.desc		= "USB Copy Button",
+		.active_low	= 1,
+	},
+	{
+		.code		= KEY_POWER,
+		.gpio		= QNAP_TS209_GPIO_KEY_RESET,
+		.desc		= "Reset Button",
+		.active_low	= 1,
+	}
+};
+
+static struct gpio_keys_platform_data qnap_ts209_button_data = {
+	.buttons	= qnap_ts209_buttons,
+	.nbuttons       = ARRAY_SIZE(qnap_ts209_buttons),
+};
+
+static struct platform_device qnap_ts209_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= { .platform_data  = &qnap_ts209_button_data, },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static struct platform_device *qnap_ts209_devices[] __initdata = {
+	&qnap_ts209_nor_flash,
+	&qnap_ts209_button_device,
+};
+
+/*
+ * QNAP TS-[12]09 specific power off method via UART1-attached PIC
+ */
+
+#define UART1_REG(x)  (UART1_BASE + ((UART_##x) << 2))
+
+static void qnap_ts209_power_off(void)
+{
+	/* 19200 baud divisor */
+	const unsigned divisor = ((ORION_TCLK + (8 * 19200)) / (16 * 19200));
+
+	pr_info("%s: triggering power-off...\n", __func__);
+
+	/* hijack uart1 and reset into sane state (19200,8n1) */
+	orion_write(UART1_REG(LCR), 0x83);
+	orion_write(UART1_REG(DLL), divisor & 0xff);
+	orion_write(UART1_REG(DLM), (divisor >> 8) & 0xff);
+	orion_write(UART1_REG(LCR), 0x03);
+	orion_write(UART1_REG(IER), 0x00);
+	orion_write(UART1_REG(FCR), 0x00);
+	orion_write(UART1_REG(MCR), 0x00);
+
+	/* send the power-off command 'A' to PIC */
+	orion_write(UART1_REG(TX), 'A');
+}
+
+static void __init qnap_ts209_init(void)
+{
+	/*
+	 * Setup basic Orion functions. Need to be called early.
+	 */
+	orion_init();
+
+	/*
+	 * Setup flash mapping
+	 */
+	orion_setup_cpu_win(ORION_DEV_BOOT, QNAP_TS209_NOR_BOOT_BASE,
+			    QNAP_TS209_NOR_BOOT_SIZE, -1);
+
+	/*
+	 * Open a special address decode windows for the PCIE WA.
+	 */
+	orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE);
+	orion_write(ORION_REGS_BASE | 0x20070, (0x7941 |
+		(((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16));
+
+	/*
+	 * Setup Multiplexing Pins --
+	 * MPP[0] Reserved
+	 * MPP[1] USB copy button (0 active)
+	 * MPP[2] Load defaults button (0 active)
+	 * MPP[3] GPIO RTC
+	 * MPP[4-5] Reserved
+	 * MPP[6] PCI Int A
+	 * MPP[7] PCI Int B
+	 * MPP[8-11] Reserved
+	 * MPP[12] SATA 0 presence
+	 * MPP[13] SATA 1 presence
+	 * MPP[14] SATA 0 active
+	 * MPP[15] SATA 1 active
+	 * MPP[16] UART1 RXD
+	 * MPP[17] UART1 TXD
+	 * MPP[18] SW_RST (0 active)
+	 * MPP[19] Reserved
+	 * MPP[20] PCI clock 0
+	 * MPP[21] PCI clock 1
+	 * MPP[22] USB 0 over current
+	 * MPP[23-25] Reserved
+	 */
+	orion_write(MPP_0_7_CTRL, 0x3);
+	orion_write(MPP_8_15_CTRL, 0x55550000);
+	orion_write(MPP_16_19_CTRL, 0x5500);
+	orion_gpio_set_valid_pins(0x3cc0fff);
+
+	/* register ts209 specific power-off method */
+	pm_power_off = qnap_ts209_power_off;
+
+	platform_add_devices(qnap_ts209_devices,
+				ARRAY_SIZE(qnap_ts209_devices));
+	i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1);
+	orion_eth_init(&qnap_ts209_eth_data);
+}
+
+MACHINE_START(TS209, "QNAP TS-109/TS-209")
+	/* Maintainer:  Byron Bradley <byron.bbradley@gmail.com> */
+	.phys_io	= ORION_REGS_BASE,
+	.io_pg_offst	= ((ORION_REGS_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= qnap_ts209_init,
+	.map_io		= orion_map_io,
+	.init_irq	= orion_init_irq,
+	.timer		= &orion_timer,
+MACHINE_END
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index cb104c2..76348f0 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -342,6 +342,27 @@
 	select CPU_TLB_V4WBI if MMU
 	select IO_36
 
+# Feroceon
+config CPU_FEROCEON
+	bool
+	depends on ARCH_ORION
+	default y
+	select CPU_32v5
+	select CPU_ABRT_EV5T
+	select CPU_CACHE_VIVT
+	select CPU_CP15_MMU
+	select CPU_COPY_V4WB if MMU
+	select CPU_TLB_V4WBI if MMU
+
+config CPU_FEROCEON_OLD_ID
+	bool "Accept early Feroceon cores with an ARM926 ID"
+	depends on CPU_FEROCEON && !CPU_ARM926T
+	default y
+	help
+	  This enables the usage of some old Feroceon cores
+	  for which the CPU ID is equal to the ARM926 ID.
+	  Relevant for Feroceon-1850 and early Feroceon-2850.
+
 # ARMv6
 config CPU_V6
 	bool "Support ARM V6 processor"
@@ -539,7 +560,7 @@
 
 config ARM_THUMB
 	bool "Support Thumb user binaries"
-	depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 || CPU_V7
+	depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 || CPU_V7 || CPU_FEROCEON
 	default y
 	help
 	  Say Y if you want to include kernel support for running user space
@@ -601,7 +622,7 @@
 
 config CPU_DCACHE_WRITETHROUGH
 	bool "Force write through D-cache"
-	depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020) && !CPU_DCACHE_DISABLE
+	depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_FEROCEON) && !CPU_DCACHE_DISABLE
 	default y if CPU_ARM925T
 	help
 	  Say Y here to use the data cache in writethrough mode. Unless you
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 7627027..44536a0 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -68,6 +68,7 @@
 obj-$(CONFIG_CPU_SA1100)	+= proc-sa1100.o
 obj-$(CONFIG_CPU_XSCALE)	+= proc-xscale.o
 obj-$(CONFIG_CPU_XSC3)		+= proc-xsc3.o
+obj-$(CONFIG_CPU_FEROCEON)	+= proc-feroceon.o
 obj-$(CONFIG_CPU_V6)		+= proc-v6.o
 obj-$(CONFIG_CPU_V7)		+= proc-v7.o
 
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
new file mode 100644
index 0000000..fa0dc7e
--- /dev/null
+++ b/arch/arm/mm/proc-feroceon.S
@@ -0,0 +1,506 @@
+/*
+ *  linux/arch/arm/mm/proc-feroceon.S: MMU functions for Feroceon
+ *
+ *  Heavily based on proc-arm926.S
+ *  Maintainer: Assaf Hoffman <hoffman@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/elf.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions.  Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define CACHE_DLIMIT	16384
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define CACHE_DLINESIZE	32
+
+	.text
+/*
+ * cpu_feroceon_proc_init()
+ */
+ENTRY(cpu_feroceon_proc_init)
+	mov	pc, lr
+
+/*
+ * cpu_feroceon_proc_fin()
+ */
+ENTRY(cpu_feroceon_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	feroceon_flush_kern_cache_all
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1000			@ ...i............
+	bic	r0, r0, #0x000e			@ ............wca.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldmfd	sp!, {pc}
+
+/*
+ * cpu_feroceon_reset(loc)
+ *
+ * Perform a soft reset of the system.  Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_feroceon_reset)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+#ifdef CONFIG_MMU
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+#endif
+	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
+	bic	ip, ip, #0x000f			@ ............wcam
+	bic	ip, ip, #0x1100			@ ...i...s........
+	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+	mov	pc, r0
+
+/*
+ * cpu_feroceon_do_idle()
+ *
+ * Called with IRQs disabled
+ */
+	.align	10
+ENTRY(cpu_feroceon_do_idle)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ Drain write buffer
+	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
+	mov	pc, lr
+
+/*
+ *	flush_user_cache_all()
+ *
+ *	Clean and invalidate all cache entries in a particular
+ *	address space.
+ */
+ENTRY(feroceon_flush_user_cache_all)
+	/* FALLTHROUGH */
+
+/*
+ *	flush_kern_cache_all()
+ *
+ *	Clean and invalidate the entire cache.
+ */
+ENTRY(feroceon_flush_kern_cache_all)
+	mov	r2, #VM_EXEC
+	mov	ip, #0
+__flush_whole_cache:
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+1:	mrc	p15, 0, r15, c7, c14, 3 	@ test,clean,invalidate
+	bne	1b
+#endif
+	tst	r2, #VM_EXEC
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcrne	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	flush_user_cache_range(start, end, flags)
+ *
+ *	Clean and invalidate a range of cache entries in the
+ *	specified address range.
+ *
+ *	- start	- start address (inclusive)
+ *	- end	- end address (exclusive)
+ *	- flags	- vm_flags describing address space
+ */
+ENTRY(feroceon_flush_user_cache_range)
+	mov	ip, #0
+	sub	r3, r1, r0			@ calculate total size
+	cmp	r3, #CACHE_DLIMIT
+	bgt	__flush_whole_cache
+1:	tst	r2, #VM_EXEC
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+#else
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+#endif
+	cmp	r0, r1
+	blo	1b
+	tst	r2, #VM_EXEC
+	mcrne	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	coherent_kern_range(start, end)
+ *
+ *	Ensure coherency between the Icache and the Dcache in the
+ *	region described by start, end.  If you have non-snooping
+ *	Harvard caches, you need to implement this function.
+ *
+ *	- start	- virtual start address
+ *	- end	- virtual end address
+ */
+ENTRY(feroceon_coherent_kern_range)
+	/* FALLTHROUGH */
+
+/*
+ *	coherent_user_range(start, end)
+ *
+ *	Ensure coherency between the Icache and the Dcache in the
+ *	region described by start, end.  If you have non-snooping
+ *	Harvard caches, you need to implement this function.
+ *
+ *	- start	- virtual start address
+ *	- end	- virtual end address
+ */
+ENTRY(feroceon_coherent_user_range)
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	flush_kern_dcache_page(void *page)
+ *
+ *	Ensure no D cache aliasing occurs, either with itself or
+ *	the I cache
+ *
+ *	- addr	- page aligned address
+ */
+ENTRY(feroceon_flush_kern_dcache_page)
+	add	r1, r0, #PAGE_SZ
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	dma_inv_range(start, end)
+ *
+ *	Invalidate (discard) the specified virtual address range.
+ *	May not write back any entries.  If 'start' or 'end'
+ *	are not cache line aligned, those lines must be written
+ *	back.
+ *
+ *	- start	- virtual start address
+ *	- end	- virtual end address
+ *
+ * (same as v4wb)
+ */
+ENTRY(feroceon_dma_inv_range)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+	tst	r0, #CACHE_DLINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
+	tst	r1, #CACHE_DLINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
+#endif
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	dma_clean_range(start, end)
+ *
+ *	Clean the specified virtual address range.
+ *
+ *	- start	- virtual start address
+ *	- end	- virtual end address
+ *
+ * (same as v4wb)
+ */
+ENTRY(feroceon_dma_clean_range)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	dma_flush_range(start, end)
+ *
+ *	Clean and invalidate the specified virtual address range.
+ *
+ *	- start	- virtual start address
+ *	- end	- virtual end address
+ */
+ENTRY(feroceon_dma_flush_range)
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
+#else
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+ENTRY(feroceon_cache_fns)
+	.long	feroceon_flush_kern_cache_all
+	.long	feroceon_flush_user_cache_all
+	.long	feroceon_flush_user_cache_range
+	.long	feroceon_coherent_kern_range
+	.long	feroceon_coherent_user_range
+	.long	feroceon_flush_kern_dcache_page
+	.long	feroceon_dma_inv_range
+	.long	feroceon_dma_clean_range
+	.long	feroceon_dma_flush_range
+
+ENTRY(cpu_feroceon_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	subs	r1, r1, #CACHE_DLINESIZE
+	bhi	1b
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_feroceon_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_feroceon_switch_mm)
+#ifdef CONFIG_MMU
+	mov	ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+@ && 'Clean & Invalidate whole DCache'
+1:	mrc	p15, 0, r15, c7, c14, 3 	@ test,clean,invalidate
+	bne	1b
+#endif
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+#endif
+	mov	pc, lr
+
+/*
+ * cpu_feroceon_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+	.align	5
+ENTRY(cpu_feroceon_set_pte_ext)
+#ifdef CONFIG_MMU
+	str	r1, [r0], #-2048		@ linux version
+
+	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+	bic	r2, r1, #PTE_SMALL_AP_MASK
+	bic	r2, r2, #PTE_TYPE_MASK
+	orr	r2, r2, #PTE_TYPE_SMALL
+
+	tst	r1, #L_PTE_USER			@ User?
+	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
+
+	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
+	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
+
+	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
+	movne	r2, #0
+
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	eor	r3, r2, #0x0a			@ C & small page?
+	tst	r3, #0x0b
+	biceq	r2, r2, #4
+#endif
+	str	r2, [r0]			@ hardware version
+	mov	r0, r0
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+#endif
+	mov	pc, lr
+
+	__INIT
+
+	.type	__feroceon_setup, #function
+__feroceon_setup:
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+#ifdef CONFIG_MMU
+	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
+#endif
+
+
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mov	r0, #4				@ disable write-back on caches explicitly
+	mcr	p15, 7, r0, c15, c0, 0
+#endif
+
+	adr	r5, feroceon_crval
+	ldmia	r5, {r5, r6}
+	mrc	p15, 0, r0, c1, c0		@ get control register v4
+	bic	r0, r0, r5
+	orr	r0, r0, r6
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+	orr	r0, r0, #0x4000			@ .1.. .... .... ....
+#endif
+	mov	pc, lr
+	.size	__feroceon_setup, . - __feroceon_setup
+
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * .011 0001 ..11 0101
+	 *
+	 */
+	.type	feroceon_crval, #object
+feroceon_crval:
+	crval	clear=0x00007f3f, mmuset=0x00003135, ucset=0x00001134
+
+	__INITDATA
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+	.type	feroceon_processor_functions, #object
+feroceon_processor_functions:
+	.word	v5t_early_abort
+	.word	cpu_feroceon_proc_init
+	.word	cpu_feroceon_proc_fin
+	.word	cpu_feroceon_reset
+	.word	cpu_feroceon_do_idle
+	.word	cpu_feroceon_dcache_clean_area
+	.word	cpu_feroceon_switch_mm
+	.word	cpu_feroceon_set_pte_ext
+	.size	feroceon_processor_functions, . - feroceon_processor_functions
+
+	.section ".rodata"
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv5te"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v5"
+	.size	cpu_elf_name, . - cpu_elf_name
+
+	.type	cpu_feroceon_name, #object
+cpu_feroceon_name:
+	.asciz	"Feroceon"
+	.size	cpu_feroceon_name, . - cpu_feroceon_name
+
+	.align
+
+	.section ".proc.info.init", #alloc, #execinstr
+
+#ifdef CONFIG_CPU_FEROCEON_OLD_ID
+	.type	__feroceon_old_id_proc_info,#object
+__feroceon_old_id_proc_info:
+	.long	0x41069260
+	.long	0xfffffff0
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	b	__feroceon_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	cpu_feroceon_name
+	.long	feroceon_processor_functions
+	.long	v4wbi_tlb_fns
+	.long	v4wb_user_fns
+	.long	feroceon_cache_fns
+	.size	__feroceon_old_id_proc_info, . - __feroceon_old_id_proc_info
+#endif
+
+	.type	__feroceon_proc_info,#object
+__feroceon_proc_info:
+	.long	0x56055310
+	.long	0xfffffff0
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	b	__feroceon_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	cpu_feroceon_name
+	.long	feroceon_processor_functions
+	.long	v4wbi_tlb_fns
+	.long	v4wb_user_fns
+	.long	feroceon_cache_fns
+	.size	__feroceon_proc_info, . - __feroceon_proc_info