diff --git a/CHANGELOG-before-U-Boot-1.1.5 b/CHANGELOG-before-U-Boot-1.1.5
index 727a7b691d59a8f07d990f5e200473fc4f7ba3c7..24041485a549127d70f4eb7522e91f696dc894b6 100644
--- a/CHANGELOG-before-U-Boot-1.1.5
+++ b/CHANGELOG-before-U-Boot-1.1.5
@@ -438,6 +438,20 @@ Changes for U-Boot 1.1.5:
 
 * Call serial_initialize() before first debug() is used.
 
+* Code cleanup
+
+* Various USB related patches
+  - Add support for mpc8xx USB device.
+  - Add support for Common Device Class - Abstract Control Model USB console.
+  - Add support for flow control in USB slave devices.
+  - Add support for switching between gserial and cdc_acm using environment.
+  - Minor changes to usbdcore_omap1510.c usbdcore_omap1510.h
+  - Update usbcore slightly to ease host enumeration.
+  - Fix non-portable endian problems in usbdcore and usbdcore_ep0.
+  - Add AdderUSB_config as a defconfig to enable usage of the USB console
+    by default with the Adder87x U-Boot port.
+  Patch by Bryan O'Donoghue <bodonoghue@codehermit.ie>, 29 May 2006
+
 * Cleanup trab board for GCC-4.x
 
 * VoiceBlue update: use new MTD flash partitioning methods, use more
diff --git a/CREDITS b/CREDITS
index 7af1b806ab0e3a651b00998cdd94475cdaf78554..4c8b896f21509c5fce74bce2f298a880a28c29fd 100644
--- a/CREDITS
+++ b/CREDITS
@@ -252,6 +252,10 @@ E: Raghu.Krishnaprasad@fci.com
 D: Support for Adder-II MPC852T evaluation board
 W: http://www.forcecomputers.com
 
+N: Sergey Kubushyn
+E: ksi@koi8.net
+D: Support for various TI DaVinci based boards.
+
 N: Bernhard Kuhn
 E: bkuhn@metrowerks.com
 D Support for Coldfire CPU; Support for Motorola M5272C3 and M5282EVB boards
diff --git a/MAINTAINERS b/MAINTAINERS
index 693b1157290f0dd8c2ffdf4e39dd85faac20d857..865f6fe0e12c671e201265ee1779a0d2175859d3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -444,6 +444,12 @@ Nishant Kamat <nskamat@ti.com>
 
 	omap1610h2		ARM926EJS
 
+Sergey Kubushyn <ksi@koi8.net>
+
+	DV-EVM			ARM926EJS
+	SONATA			ARM926EJS
+	SCHMOOGIE		ARM926EJS
+
 Prakash Kumar <prakash@embedx.com>
 
 	cerf250			xscale
diff --git a/MAKEALL b/MAKEALL
index 3e186ccd5a3d0388c0f2eeed389f73f94bf99bdf..129c14c9f9a9c34b67ac40908ceca78feeab0a6a 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -26,124 +26,281 @@ LIST=""
 ## MPC5xx Systems
 #########################################################################
 
-LIST_5xx="	\
-	cmi_mpc5xx							\
+LIST_5xx="		\
+	cmi_mpc5xx	\
 "
 
 #########################################################################
 ## MPC5xxx Systems
 #########################################################################
 
-LIST_5xxx="	\
-	BC3450		cm5200		cpci5200	EVAL5200	\
-	fo300		icecube_5100	icecube_5200	lite5200b	\
-	mcc200		mecp5200	motionpro	o2dnt		\
-	pf5200		PM520		TB5200		Total5100	\
-	Total5200	Total5200_Rev2	TQM5200		TQM5200_B	\
-	TQM5200S	v38b						\
+LIST_5xxx="		\
+	BC3450		\
+	cm5200		\
+	cpci5200	\
+	EVAL5200	\
+	fo300		\
+	icecube_5100	\
+	icecube_5200	\
+	lite5200b	\
+	mcc200		\
+	mecp5200	\
+	motionpro	\
+	o2dnt		\
+	pf5200		\
+	PM520		\
+	TB5200		\
+	Total5100	\
+	Total5200	\
+	Total5200_Rev2	\
+	TQM5200		\
+	TQM5200_B	\
+	TQM5200S	\
+	v38b		\
 "
 
 #########################################################################
 ## MPC512x Systems
 #########################################################################
 
-LIST_512x="	\
-	ads5121							\
+LIST_512x="		\
+	ads5121		\
 "
 
 #########################################################################
 ## MPC8xx Systems
 #########################################################################
-LIST_8xx="	\
-	Adder87x	GENIETV		MBX860T		R360MPI		\
-	AdderII		GTH		MHPC		RBC823		\
-	ADS860		hermes		MPC86xADS	rmu		\
-	AMX860		IAD210		MPC885ADS	RPXClassic	\
-	c2mon		ICU862_100MHz	MVS1		RPXlite		\
-	CCM		IP860		NETPHONE	RPXlite_DW	\
-	cogent_mpc8xx	IVML24		NETTA		RRvision	\
-	ELPT860		IVML24_128	NETTA2		SM850		\
-	EP88x		IVML24_256	NETTA_ISDN	spc1920		\
-	ESTEEM192E	IVMS8		NETVIA		SPD823TS	\
-	ETX094		IVMS8_128	NETVIA_V2	svm_sc8xx	\
-	FADS823		IVMS8_256	NX823		SXNI855T	\
-	FADS850SAR	KUP4K		pcu_e		TOP860		\
-	FADS860T	KUP4X		QS823		TQM823L		\
-	FLAGADM		LANTEC		QS850		TQM823L_LCD	\
-	FPS850L		lwmon		QS860T		TQM850L		\
-	GEN860T		MBX		quantum		TQM855L		\
-	GEN860T_SC					TQM860L		\
-							TQM885D		\
-							uc100		\
-							v37		\
+LIST_8xx="		\
+	Adder87x	\
+	AdderII		\
+	ADS860		\
+	AMX860		\
+	c2mon		\
+	CCM		\
+	cogent_mpc8xx	\
+	ELPT860		\
+	EP88x		\
+	ESTEEM192E	\
+	ETX094		\
+	FADS823		\
+	FADS850SAR	\
+	FADS860T	\
+	FLAGADM		\
+	FPS850L		\
+	GEN860T		\
+	GEN860T_SC	\
+	GENIETV		\
+	GTH		\
+	hermes		\
+	IAD210		\
+	ICU862_100MHz	\
+	IP860		\
+	IVML24		\
+	IVML24_128	\
+	IVML24_256	\
+	IVMS8		\
+	IVMS8_128	\
+	IVMS8_256	\
+	KUP4K		\
+	KUP4X		\
+	LANTEC		\
+	lwmon		\
+	MBX		\
+	MBX860T		\
+	MHPC		\
+	MPC86xADS	\
+	MPC885ADS	\
+	MVS1		\
+	NETPHONE	\
+	NETTA		\
+	NETTA2		\
+	NETTA_ISDN	\
+	NETVIA		\
+	NETVIA_V2	\
+	NX823		\
+	pcu_e		\
+	QS823		\
+	QS850		\
+	QS860T		\
+	quantum		\
+	R360MPI		\
+	RBC823		\
+	rmu		\
+	RPXClassic	\
+	RPXlite		\
+	RPXlite_DW	\
+	RRvision	\
+	SM850		\
+	spc1920		\
+	SPD823TS	\
+	svm_sc8xx	\
+	SXNI855T	\
+	TOP860		\
+	TQM823L		\
+	TQM823L_LCD	\
+	TQM850L		\
+	TQM855L		\
+	TQM860L		\
+	TQM885D		\
+	uc100		\
+	v37		\
 "
 
 #########################################################################
 ## PPC4xx Systems
 #########################################################################
 
-LIST_4xx="	\
-	acadia		acadia_nand	ADCIOP		alpr		\
-	AP1000		AR405		ASH405		bamboo		\
-	bamboo_nand	bubinga		CANBT		CMS700		\
-	CPCI2DP		CPCI405		CPCI4052	CPCI405AB	\
-	CPCI405DT	CPCI440		CPCIISER4	CRAYL1		\
-	csb272		csb472		DASA_SIM	DP405		\
-	DU405		ebony		ERIC		EXBITGEN	\
-	G2000		HH405		HUB405		JSE		\
-	KAREF		katmai		luan		lwmon5		\
-	METROBOX	MIP405		MIP405T		ML2		\
-	ml300		ocotea		OCRTC		ORSG		\
-	p3p440		PCI405		pcs440ep	PIP405		\
-	PLU405		PMC405		PPChameleonEVB	sbc405		\
-	sc3		sequoia		sequoia_nand	taishan		\
-	VOH405		VOM405		W7OLMC		W7OLMG		\
-	walnut		WUH405		XPEDITE1K	yellowstone	\
-	yosemite	yucca						\
+LIST_4xx="		\
+	acadia		\
+	acadia_nand	\
+	ADCIOP		\
+	alpr		\
+	AP1000		\
+	AR405		\
+	ASH405		\
+	bamboo		\
+	bamboo_nand	\
+	bubinga		\
+	CANBT		\
+	CMS700		\
+	CPCI2DP		\
+	CPCI405		\
+	CPCI4052	\
+	CPCI405AB	\
+	CPCI405DT	\
+	CPCI440		\
+	CPCIISER4	\
+	CRAYL1		\
+	csb272		\
+	csb472		\
+	DASA_SIM	\
+	DP405		\
+	DU405		\
+	ebony		\
+	ERIC		\
+	EXBITGEN	\
+	G2000		\
+	HH405		\
+	HUB405		\
+	JSE		\
+	KAREF		\
+	katmai		\
+	luan		\
+	lwmon5		\
+	METROBOX	\
+	MIP405		\
+	MIP405T		\
+	ML2		\
+	ml300		\
+	ocotea		\
+	OCRTC		\
+	ORSG		\
+	p3p440		\
+	PCI405		\
+	pcs440ep	\
+	PIP405		\
+	PLU405		\
+	PMC405		\
+	PPChameleonEVB	\
+	sbc405		\
+	sc3		\
+	sequoia		\
+	sequoia_nand	\
+	taishan		\
+	VOH405		\
+	VOM405		\
+	W7OLMC		\
+	W7OLMG		\
+	walnut		\
+	WUH405		\
+	XPEDITE1K	\
+	yellowstone	\
+	yosemite	\
+	yucca		\
 "
 
 #########################################################################
 ## MPC8220 Systems
 #########################################################################
 
-LIST_8220="	\
-	Alaska8220	Yukon8220					\
+LIST_8220="		\
+	Alaska8220	\
+	Yukon8220	\
 "
 
 #########################################################################
 ## MPC824x Systems
 #########################################################################
 
-LIST_824x="	\
-	A3000		barco		BMW		CPC45		\
-	CU824		debris		eXalion		HIDDEN_DRAGON	\
-			MOUSSE		MUSENKI		MVBLUE		\
-	OXC		PN62		Sandpoint8240	Sandpoint8245	\
-	sbc8240		SL8245		utx8245				\
+LIST_824x="		\
+	A3000		\
+	barco		\
+	BMW		\
+	CPC45		\
+	CU824		\
+	debris		\
+	eXalion		\
+	HIDDEN_DRAGON	\
+	MOUSSE		\
+	MUSENKI		\
+	MVBLUE		\
+	OXC		\
+	PN62		\
+	Sandpoint8240	\
+	Sandpoint8245	\
+	sbc8240		\
+	SL8245		\
+	utx8245		\
 "
 
 #########################################################################
 ## MPC8260 Systems (includes 8250, 8255 etc.)
 #########################################################################
 
-LIST_8260="	\
-	atc		cogent_mpc8260	CPU86		CPU87		\
-	ep8248		ep8260		ep82xxm		gw8260		\
-	hymod		IPHASE4539	ISPAN		MPC8260ADS	\
-	MPC8266ADS	MPC8272ADS	PM826		PM828		\
-	ppmc8260	Rattler8248	RPXsuper	rsdproto	\
-	sacsng		sbc8260		SCM		TQM8260_AC	\
-	TQM8260_AD	TQM8260_AE	ZPC1900				\
+LIST_8260="		\
+	atc		\
+	cogent_mpc8260	\
+	CPU86		\
+	CPU87		\
+	ep8248		\
+	ep8260		\
+	ep82xxm		\
+	gw8260		\
+	hymod		\
+	IPHASE4539	\
+	ISPAN		\
+	MPC8260ADS	\
+	MPC8266ADS	\
+	MPC8272ADS	\
+	PM826		\
+	PM828		\
+	ppmc8260	\
+	Rattler8248	\
+	RPXsuper	\
+	rsdproto	\
+	sacsng		\
+	sbc8260		\
+	SCM		\
+	TQM8260_AC	\
+	TQM8260_AD	\
+	TQM8260_AE	\
+	ZPC1900		\
 "
 
 #########################################################################
 ## MPC83xx Systems (includes 8349, etc.)
 #########################################################################
 
-LIST_83xx="	\
-	MPC8313ERDB_33	MPC8313ERDB_66	MPC832XEMDS	MPC8349EMDS	\
-	MPC8349ITX	MPC8349ITXGP	MPC8360EMDS	sbc8349		\
-	TQM834x								\
+LIST_83xx="		\
+	MPC8313ERDB_33	\
+	MPC8313ERDB_66	\
+	MPC832XEMDS	\
+	MPC8349EMDS	\
+	MPC8349ITX	\
+	MPC8349ITXGP	\
+	MPC8360EMDS	\
+	sbc8349		\
+	TQM834x		\
 "
 
 
@@ -151,123 +308,226 @@ LIST_83xx="	\
 ## MPC85xx Systems (includes 8540, 8560 etc.)
 #########################################################################
 
-LIST_85xx="	\
-	MPC8540ADS	MPC8540EVAL	MPC8541CDS	MPC8544DS	\
-	MPC8548CDS	MPC8555CDS	MPC8560ADS	MPC8568MDS	\
-	PM854		PM856		sbc8540		sbc8560		\
-	stxgp3		stxssa		TQM8540		TQM8541		\
-	TQM8555		TQM8560						\
+LIST_85xx="		\
+	MPC8540ADS	\
+	MPC8540EVAL	\
+	MPC8541CDS	\
+	MPC8544DS	\
+	MPC8548CDS	\
+	MPC8555CDS	\
+	MPC8560ADS	\
+	MPC8568MDS	\
+	PM854		\
+	PM856		\
+	sbc8540		\
+	sbc8560		\
+	stxgp3		\
+	stxssa		\
+	TQM8540		\
+	TQM8541		\
+	TQM8555		\
+	TQM8560		\
 "
 
 #########################################################################
 ## MPC86xx Systems
 #########################################################################
 
-LIST_86xx="	\
-    MPC8641HPCN	\
+LIST_86xx="		\
+	MPC8641HPCN	\
 "
 
 #########################################################################
 ## 74xx/7xx Systems
 #########################################################################
 
-LIST_74xx="	\
-	DB64360		DB64460		EVB64260	P3G4		\
-	p3m7448		PCIPPC2		PCIPPC6		ZUMA		\
-	mpc7448hpc2
+LIST_74xx="		\
+	DB64360		\
+	DB64460		\
+	EVB64260	\
+	mpc7448hpc2	\
+	P3G4		\
+	p3m7448		\
+	PCIPPC2		\
+	PCIPPC6		\
+	ZUMA		\
 "
 
-LIST_7xx="	\
-	BAB7xx		CPCI750		ELPPC		p3m750		\
-	ppmc7xx								\
+LIST_7xx="		\
+	BAB7xx		\
+	CPCI750		\
+	ELPPC		\
+	p3m750		\
+	ppmc7xx		\
 "
 
-LIST_ppc="${LIST_5xx}  ${LIST_5xxx}		\
-	  ${LIST_8xx}				\
-	  ${LIST_8220} ${LIST_824x} ${LIST_8260} \
-	  ${LIST_83xx}				\
-	  ${LIST_85xx}				\
-	  ${LIST_86xx}				\
-	  ${LIST_4xx}				\
-	  ${LIST_74xx} ${LIST_7xx}"
+LIST_ppc="		\
+	${LIST_5xx}	\
+	${LIST_5xxx}	\
+	${LIST_8xx}	\
+	${LIST_8220}	\
+	${LIST_824x}	\
+	${LIST_8260}	\
+	${LIST_83xx}	\
+	${LIST_85xx}	\
+	${LIST_86xx}	\
+	${LIST_4xx}	\
+	${LIST_74xx}	\
+	${LIST_7xx}	\
+"
 
 #########################################################################
 ## StrongARM Systems
 #########################################################################
 
-LIST_SA="assabet dnp1110 gcplus lart shannon"
+LIST_SA="		\
+	assabet		\
+	dnp1110		\
+	gcplus		\
+	lart		\
+	shannon		\
+"
 
 #########################################################################
 ## ARM7 Systems
 #########################################################################
 
-LIST_ARM7="	\
-	armadillo	B2		ep7312		evb4510		\
-	impa7		integratorap	ap7		ap720t		\
-	lpc2292sodimm	modnet50	SMN42				\
+LIST_ARM7="		\
+	ap7		\
+	ap720t		\
+	armadillo	\
+	B2		\
+	ep7312		\
+	evb4510		\
+	impa7		\
+	integratorap	\
+	lpc2292sodimm	\
+	modnet50	\
+	SMN42		\
 "
 
 #########################################################################
 ## ARM9 Systems
 #########################################################################
 
-LIST_ARM9="	\
-	at91rm9200dk	cmc_pu2						\
-	ap920t		ap922_XA10	ap926ejs	ap946es		\
-	ap966		cp920t		cp922_XA10	cp926ejs	\
-	cp946es		cp966		lpd7a400	mp2usb		\
-	mx1ads		mx1fs2		netstar		omap1510inn	\
-	omap1610h2	omap1610inn	omap730p2	sbc2410x	\
-	scb9328		smdk2400	smdk2410	trab		\
-	VCMA9		versatile	versatileab	versatilepb	\
-	voiceblue							\
+LIST_ARM9="			\
+	at91rm9200dk		\
+	cmc_pu2			\
+	ap920t			\
+	ap922_XA10		\
+	ap926ejs		\
+	ap946es			\
+	ap966			\
+	cp920t			\
+	cp922_XA10		\
+	cp926ejs		\
+	cp946es			\
+	cp966			\
+	lpd7a400		\
+	mp2usb			\
+	mx1ads			\
+	mx1fs2			\
+	netstar			\
+	omap1510inn		\
+	omap1610h2		\
+	omap1610inn		\
+	omap730p2		\
+	sbc2410x		\
+	scb9328			\
+	smdk2400		\
+	smdk2410		\
+	trab			\
+	VCMA9			\
+	versatile		\
+	versatileab		\
+	versatilepb		\
+	voiceblue		\
+	davinci_dvevm		\
+	davinci_schmoogie	\
+	davinci_sonata		\
 "
 
 #########################################################################
 ## ARM10 Systems
 #########################################################################
-LIST_ARM10="	\
-	integratorcp	cp1026						\
+LIST_ARM10="		\
+	integratorcp	\
+	cp1026		\
 "
 
 #########################################################################
 ## ARM11 Systems
 #########################################################################
-LIST_ARM11="	\
-	cp1136		omap2420h4					\
+LIST_ARM11="		\
+	cp1136		\
+	omap2420h4	\
 "
 
 #########################################################################
 ## Xscale Systems
 #########################################################################
 
-LIST_pxa="	\
-	adsvix		cerf250		cradle		csb226		\
-	delta		innokom		lubbock		pleb2		\
-	pxa255_idp	wepep250	xaeniax		xm250		\
-	xsengine	zylonite					\
+LIST_pxa="		\
+	adsvix		\
+	cerf250		\
+	cradle		\
+	csb226		\
+	delta		\
+	innokom		\
+	lubbock		\
+	pleb2		\
+	pxa255_idp	\
+	wepep250	\
+	xaeniax		\
+	xm250		\
+	xsengine	\
+	zylonite	\
 "
 
-LIST_ixp="ixdp425	ixdpg425	pdnb3		scpu"
+LIST_ixp="		\
+	ixdp425		\
+	ixdpg425	\
+	pdnb3		\
+	scpu		\
+"
 
 
-LIST_arm="	\
-	${LIST_SA}							\
-	${LIST_ARM7} ${LIST_ARM9} ${LIST_ARM10} ${LIST_ARM11}		\
-	${LIST_pxa} ${LIST_ixp}						\
+LIST_arm="		\
+	${LIST_SA}	\
+	${LIST_ARM7}	\
+	${LIST_ARM9}	\
+	${LIST_ARM10}	\
+	${LIST_ARM11}	\
+	${LIST_pxa}	\
+	${LIST_ixp}	\
 "
 
 #########################################################################
 ## MIPS Systems		(default = big endian)
 #########################################################################
 
-LIST_mips4kc="incaip"
+LIST_mips4kc="		\
+	incaip		\
+"
 
-LIST_mips5kc="purple"
+LIST_mips5kc="		\
+	purple		\
+"
 
-LIST_au1xx0="dbau1000 dbau1100 dbau1500 dbau1550 dbau1550_el gth2"
+LIST_au1xx0="		\
+	dbau1000	\
+	dbau1100	\
+	dbau1500	\
+	dbau1550	\
+	dbau1550_el	\
+	gth2		\
+"
 
-LIST_mips="${LIST_mips4kc} ${LIST_mips5kc} ${LIST_au1xx0}"
+LIST_mips="		\
+	${LIST_mips4kc}	\
+	${LIST_mips5kc}	\
+	${LIST_au1xx0}	\
+"
 
 #########################################################################
 ## MIPS Systems		(little endian)
@@ -277,36 +537,55 @@ LIST_mips4kc_el=""
 
 LIST_mips5kc_el=""
 
-LIST_au1xx0_el="dbau1550_el"
+LIST_au1xx0_el="	\
+	dbau1550_el	\
+"
 
-LIST_mips_el="${LIST_mips4kc_el} ${LIST_mips5kc_el} ${LIST_au1xx0_el}"
+LIST_mips_el="			\
+	${LIST_mips4kc_el}	\
+	${LIST_mips5kc_el}	\
+	${LIST_au1xx0_el}	\
+"
 
 #########################################################################
 ## i386 Systems
 #########################################################################
 
-LIST_I486="sc520_cdp sc520_spunk sc520_spunk_rel"
+LIST_I486="		\
+	sc520_cdp	\
+	sc520_spunk	\
+	sc520_spunk_rel	\
+"
 
-LIST_x86="${LIST_I486}"
+LIST_x86="		\
+	${LIST_I486}	\
+"
 
 #########################################################################
 ## NIOS Systems
 #########################################################################
 
-LIST_nios="	\
-	ADNPESC1		ADNPESC1_base_32			\
-	ADNPESC1_DNPEVA2_base_32					\
-	DK1C20			DK1C20_standard_32			\
-	DK1S10			DK1S10_standard_32 DK1S10_mtx_ldk_20	\
+LIST_nios="			\
+	ADNPESC1		\
+	ADNPESC1_base_32	\
+	ADNPESC1_DNPEVA2_base_32\
+	DK1C20			\
+	DK1C20_standard_32	\
+	DK1S10			\
+	DK1S10_standard_32	\
+	DK1S10_mtx_ldk_20	\
 "
 
 #########################################################################
 ## Nios-II Systems
 #########################################################################
 
-LIST_nios2="	\
-	EP1C20		EP1S10		EP1S40				\
-	PCI5441		PK1C20						\
+LIST_nios2="		\
+	EP1C20		\
+	EP1S10		\
+	EP1S40		\
+	PCI5441		\
+	PK1C20		\
 "
 
 #########################################################################
@@ -314,31 +593,44 @@ LIST_nios2="	\
 #########################################################################
 
 LIST_microblaze="	\
-	suzaku		ml401		xupv2p
+	suzaku		\
+	ml401		\
+	xupv2p		\
 "
 
 #########################################################################
 ## ColdFire Systems
 #########################################################################
 
-LIST_coldfire="	\
-	cobra5272	EB+MCF-EV123	EB+MCF-EV123_internal		\
-	idmr		M5271EVB	M5272C3		M5282EVB	\
-	TASREG		r5200		M5271EVB			\
+LIST_coldfire="			\
+	cobra5272		\
+	EB+MCF-EV123		\
+	EB+MCF-EV123_internal	\
+	idmr			\
+	M5271EVB		\
+	M5272C3			\
+	M5282EVB		\
+	TASREG			\
+	r5200			\
 "
 
 #########################################################################
 ## AVR32 Systems
 #########################################################################
 
-LIST_avr32="atstk1002"
+LIST_avr32="		\
+	atstk1002	\
+"
 
 #########################################################################
 ## Blackfin Systems
 #########################################################################
 
-LIST_blackfin=" \
-	bf533-ezkit	bf533-stamp	bf537-stamp	bf561-ezkit	\
+LIST_blackfin="		\
+	bf533-ezkit	\
+	bf533-stamp	\
+	bf537-stamp	\
+	bf561-ezkit	\
 "
 
 #-----------------------------------------------------------------------
diff --git a/Makefile b/Makefile
index cf3fbcbf20b69c93218a282695a51b720559e183..eef51cc4473609d9a650edb5b7ba51f095e865b7 100644
--- a/Makefile
+++ b/Makefile
@@ -34,6 +34,7 @@ HOSTARCH := $(shell uname -m | \
 	    -e s/arm.*/arm/ \
 	    -e s/sa110/arm/ \
 	    -e s/powerpc/ppc/ \
+	    -e s/ppc64/ppc/ \
 	    -e s/macppc/ppc/)
 
 HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
@@ -122,7 +123,7 @@ ifeq ($(HOSTARCH),$(ARCH))
 CROSS_COMPILE =
 else
 ifeq ($(ARCH),ppc)
-CROSS_COMPILE = powerpc-linux-
+CROSS_COMPILE = ppc_8xx-
 endif
 ifeq ($(ARCH),arm)
 CROSS_COMPILE = arm-linux-
@@ -657,6 +658,9 @@ AdderII_config  \
 	@echo "#define CONFIG_MPC852T" > $(obj)include/config.h)
 	@$(MKCONFIG) -a Adder ppc mpc8xx adder
 
+AdderUSB_config:	unconfig
+	@./mkconfig -a AdderUSB ppc mpc8xx adder
+
 ADS860_config     \
 FADS823_config    \
 FADS850SAR_config \
@@ -1662,15 +1666,18 @@ MPC8313ERDB_66_config: unconfig
 	@mkdir -p $(obj)include
 	@echo "" >$(obj)include/config.h ; \
 	if [ "$(findstring _33_,$@)" ] ; then \
-		echo "...33M ..." ; \
+		echo -n "...33M ..." ; \
 		echo "#define CFG_33MHZ" >>$(obj)include/config.h ; \
 	fi ; \
 	if [ "$(findstring _66_,$@)" ] ; then \
-		echo "...66M..." ; \
+		echo -n "...66M..." ; \
 		echo "#define CFG_66MHZ" >>$(obj)include/config.h ; \
 	fi ;
 	@$(MKCONFIG) -a MPC8313ERDB ppc mpc83xx mpc8313erdb
 
+MPC8323ERDB_config:	unconfig
+	@$(MKCONFIG) -a MPC8323ERDB ppc mpc83xx mpc8323erdb freescale
+
 MPC832XEMDS_config \
 MPC832XEMDS_HOST_33_config \
 MPC832XEMDS_HOST_66_config \
@@ -1678,7 +1685,7 @@ MPC832XEMDS_SLAVE_config:	unconfig
 	@mkdir -p $(obj)include
 	@echo "" >$(obj)include/config.h ; \
 	if [ "$(findstring _HOST_,$@)" ] ; then \
-		echo "... PCI HOST " ; \
+		echo -n "... PCI HOST " ; \
 		echo "#define CONFIG_PCI" >>$(obj)include/config.h ; \
 	fi ; \
 	if [ "$(findstring _SLAVE_,$@)" ] ; then \
@@ -1687,11 +1694,11 @@ MPC832XEMDS_SLAVE_config:	unconfig
 		echo "#define CONFIG_PCISLAVE" >>$(obj)include/config.h ; \
 	fi ; \
 	if [ "$(findstring _33_,$@)" ] ; then \
-		echo "...33M ..." ; \
+		echo -n "...33M ..." ; \
 		echo "#define PCI_33M" >>$(obj)include/config.h ; \
 	fi ; \
 	if [ "$(findstring _66_,$@)" ] ; then \
-		echo "...66M..." ; \
+		echo -n "...66M..." ; \
 		echo "#define PCI_66M" >>$(obj)include/config.h ; \
 	fi ;
 	@$(MKCONFIG) -a MPC832XEMDS ppc mpc83xx mpc832xemds
@@ -1720,7 +1727,7 @@ MPC8360EMDS_SLAVE_config:	unconfig
 	@mkdir -p $(obj)include
 	@echo "" >$(obj)include/config.h ; \
 	if [ "$(findstring _HOST_,$@)" ] ; then \
-		echo "... PCI HOST " ; \
+		echo -n "... PCI HOST " ; \
 		echo "#define CONFIG_PCI" >>$(obj)include/config.h ; \
 	fi ; \
 	if [ "$(findstring _SLAVE_,$@)" ] ; then \
@@ -1729,11 +1736,11 @@ MPC8360EMDS_SLAVE_config:	unconfig
 		echo "#define CONFIG_PCISLAVE" >>$(obj)include/config.h ; \
 	fi ; \
 	if [ "$(findstring _33_,$@)" ] ; then \
-		echo "...33M ..." ; \
+		echo -n "...33M ..." ; \
 		echo "#define PCI_33M" >>$(obj)include/config.h ; \
 	fi ; \
 	if [ "$(findstring _66_,$@)" ] ; then \
-		echo "...66M..." ; \
+		echo -n "...66M..." ; \
 		echo "#define PCI_66M" >>$(obj)include/config.h ; \
 	fi ;
 	@$(MKCONFIG) -a MPC8360EMDS ppc mpc83xx mpc8360emds
@@ -2014,6 +2021,15 @@ omap1510inn_config :	unconfig
 omap5912osk_config :	unconfig
 	@$(MKCONFIG) $(@:_config=) arm arm926ejs omap5912osk NULL omap
 
+davinci_dvevm_config :	unconfig
+	@$(MKCONFIG) $(@:_config=) arm arm926ejs dv-evm davinci davinci
+
+davinci_schmoogie_config :	unconfig
+	@$(MKCONFIG) $(@:_config=) arm arm926ejs schmoogie davinci davinci
+
+davinci_sonata_config :	unconfig
+	@$(MKCONFIG) $(@:_config=) arm arm926ejs sonata davinci davinci
+
 omap1610inn_config \
 omap1610inn_cs0boot_config \
 omap1610inn_cs3boot_config \
diff --git a/README b/README
index 852ad72acdc09c80c45f3debf49b7908aed7bd35..398ea7e791c038dfc479c098be74c5d46bde8cbe 100644
--- a/README
+++ b/README
@@ -228,113 +228,9 @@ build a config tool - later.
 
 The following options need to be configured:
 
-- CPU Type:	Define exactly one of
-
-		PowerPC based CPUs:
-		-------------------
-		CONFIG_MPC823,	CONFIG_MPC850,	CONFIG_MPC855,	CONFIG_MPC860
-	or	CONFIG_MPC5xx
-	or	CONFIG_MPC8220
-	or	CONFIG_MPC824X, CONFIG_MPC8260
-	or	CONFIG_MPC85xx
-	or	CONFIG_IOP480
-	or	CONFIG_405GP
-	or	CONFIG_405EP
-	or	CONFIG_440
-	or	CONFIG_MPC74xx
-	or	CONFIG_750FX
-
-		ARM based CPUs:
-		---------------
-		CONFIG_SA1110
-		CONFIG_ARM7
-		CONFIG_PXA250
-		CONFIG_CPU_MONAHANS
-
-		MicroBlaze based CPUs:
-		----------------------
-		CONFIG_MICROBLAZE
-
-		Nios-2 based CPUs:
-		----------------------
-		CONFIG_NIOS2
-
-		AVR32 based CPUs:
-		----------------------
-		CONFIG_AT32AP
-
-- Board Type:	Define exactly one of
-
-		PowerPC based boards:
-		---------------------
-
-		CONFIG_ADCIOP		CONFIG_FPS860L		CONFIG_OXC
-		CONFIG_ADS860		CONFIG_GEN860T		CONFIG_PCI405
-		CONFIG_AMX860		CONFIG_GENIETV		CONFIG_PCIPPC2
-		CONFIG_AP1000		CONFIG_GTH		CONFIG_PCIPPC6
-		CONFIG_AR405		CONFIG_gw8260		CONFIG_pcu_e
-		CONFIG_BAB7xx		CONFIG_hermes		CONFIG_PIP405
-		CONFIG_BC3450		CONFIG_hymod		CONFIG_PM826
-		CONFIG_c2mon		CONFIG_IAD210		CONFIG_ppmc8260
-		CONFIG_CANBT		CONFIG_ICU862		CONFIG_QS823
-		CONFIG_CCM		CONFIG_IP860		CONFIG_QS850
-		CONFIG_CMI		CONFIG_IPHASE4539	CONFIG_QS860T
-		CONFIG_cogent_mpc8260	CONFIG_IVML24		CONFIG_RBC823
-		CONFIG_cogent_mpc8xx	CONFIG_IVML24_128	CONFIG_RPXClassic
-		CONFIG_CPCI405		CONFIG_IVML24_256	CONFIG_RPXlite
-		CONFIG_CPCI4052		CONFIG_IVMS8		CONFIG_RPXsuper
-		CONFIG_CPCIISER4	CONFIG_IVMS8_128	CONFIG_rsdproto
-		CONFIG_CPU86		CONFIG_IVMS8_256	CONFIG_sacsng
-		CONFIG_CRAYL1		CONFIG_JSE		CONFIG_Sandpoint8240
-		CONFIG_CSB272		CONFIG_LANTEC		CONFIG_Sandpoint8245
-		CONFIG_CU824		CONFIG_LITE5200B	CONFIG_sbc8260
-		CONFIG_DASA_SIM		CONFIG_lwmon		CONFIG_sbc8560
-		CONFIG_DB64360		CONFIG_MBX		CONFIG_SM850
-		CONFIG_DB64460		CONFIG_MBX860T		CONFIG_SPD823TS
-		CONFIG_DU405		CONFIG_MHPC		CONFIG_STXGP3
-		CONFIG_DUET_ADS		CONFIG_MIP405		CONFIG_SXNI855T
-		CONFIG_EBONY		CONFIG_MOUSSE		CONFIG_TQM823L
-		CONFIG_ELPPC		CONFIG_MPC8260ADS	CONFIG_TQM8260
-		CONFIG_ELPT860		CONFIG_MPC8540ADS	CONFIG_TQM850L
-		CONFIG_ep8260		CONFIG_MPC8540EVAL	CONFIG_TQM855L
-		CONFIG_ERIC		CONFIG_MPC8560ADS	CONFIG_TQM860L
-		CONFIG_ESTEEM192E	CONFIG_MUSENKI		CONFIG_TTTech
-		CONFIG_ETX094		CONFIG_MVS1		CONFIG_UTX8245
-		CONFIG_EVB64260		CONFIG_NETPHONE		CONFIG_V37
-		CONFIG_FADS823		CONFIG_NETTA		CONFIG_W7OLMC
-		CONFIG_FADS850SAR	CONFIG_NETVIA		CONFIG_W7OLMG
-		CONFIG_FADS860T		CONFIG_NX823		CONFIG_WALNUT
-		CONFIG_FLAGADM		CONFIG_OCRTC		CONFIG_ZPC1900
-		CONFIG_FPS850L		CONFIG_ORSG		CONFIG_ZUMA
-
-		ARM based boards:
-		-----------------
-
-		CONFIG_ARMADILLO,	CONFIG_AT91RM9200DK,	CONFIG_CERF250,
-		CONFIG_CSB637,		CONFIG_DELTA,		CONFIG_DNP1110,
-		CONFIG_EP7312,		CONFIG_H2_OMAP1610,	CONFIG_HHP_CRADLE,
-		CONFIG_IMPA7,	    CONFIG_INNOVATOROMAP1510,	CONFIG_INNOVATOROMAP1610,
-		CONFIG_KB9202,		CONFIG_LART,		CONFIG_LPD7A400,
-		CONFIG_LUBBOCK,		CONFIG_OSK_OMAP5912,	CONFIG_OMAP2420H4,
-		CONFIG_PLEB2,		CONFIG_SHANNON,		CONFIG_P2_OMAP730,
-		CONFIG_SMDK2400,	CONFIG_SMDK2410,	CONFIG_TRAB,
-		CONFIG_VCMA9
-
-		MicroBlaze based boards:
-		------------------------
-
-		CONFIG_SUZAKU
-
-		Nios-2 based boards:
-		------------------------
-
-		CONFIG_PCI5441 CONFIG_PK1C20
-		CONFIG_EP1C20 CONFIG_EP1S10 CONFIG_EP1S40
-
-		AVR32 based boards:
-		-------------------
-
-		CONFIG_ATSTK1000
+- CPU Type:	Define exactly one, e.g. CONFIG_MPC85XX.
+
+- Board Type:	Define exactly one, e.g. CONFIG_MPC8540ADS.
 
 - CPU Daughterboard Type: (if CONFIG_ATSTK1000 is defined)
 		Define exactly one of
@@ -893,6 +789,71 @@ The following options need to be configured:
 			CONFIG_USB_CONFIG
 				for differential drivers: 0x00001000
 				for single ended drivers: 0x00005000
+			CFG_USB_EVENT_POLL
+				May be defined to allow interrupt polling
+				instead of using asynchronous interrupts
+
+- USB Device:
+		Define the below if you wish to use the USB console.
+		Once firmware is rebuilt from a serial console issue the
+		command "setenv stdin usbtty; setenv stdout usbtty" and
+		attach your usb cable. The Unix command "dmesg" should print
+		it has found a new device. The environment variable usbtty
+		can be set to gserial or cdc_acm to enable your device to
+		appear to a USB host as a Linux gserial device or a
+		Common Device Class Abstract Control Model serial device.
+		If you select usbtty = gserial you should be able to enumerate
+		a Linux host by
+		# modprobe usbserial vendor=0xVendorID product=0xProductID
+		else if using cdc_acm, simply setting the environment
+		variable usbtty to be cdc_acm should suffice. The following
+		might be defined in YourBoardName.h
+
+			CONFIG_USB_DEVICE
+			Define this to build a UDC device
+
+			CONFIG_USB_TTY
+			Define this to have a tty type of device available to
+			talk to the UDC device
+
+			CFG_CONSOLE_IS_IN_ENV
+			Define this if you want stdin, stdout &/or stderr to
+			be set to usbtty.
+
+			mpc8xx:
+				CFG_USB_EXTC_CLK 0xBLAH
+				Derive USB clock from external clock "blah"
+				- CFG_USB_EXTC_CLK 0x02
+
+				CFG_USB_BRG_CLK 0xBLAH
+				Derive USB clock from brgclk
+				- CFG_USB_BRG_CLK 0x04
+
+		If you have a USB-IF assigned VendorID then you may wish to
+		define your own vendor specific values either in BoardName.h
+		or directly in usbd_vendor_info.h. If you don't define
+		CONFIG_USBD_MANUFACTURER, CONFIG_USBD_PRODUCT_NAME,
+		CONFIG_USBD_VENDORID and CONFIG_USBD_PRODUCTID, then U-Boot
+		should pretend to be a Linux device to it's target host.
+
+			CONFIG_USBD_MANUFACTURER
+			Define this string as the name of your company for
+			- CONFIG_USBD_MANUFACTURER "my company"
+
+			CONFIG_USBD_PRODUCT_NAME
+			Define this string as the name of your product
+			- CONFIG_USBD_PRODUCT_NAME "acme usb device"
+
+			CONFIG_USBD_VENDORID
+			Define this as your assigned Vendor ID from the USB
+			Implementors Forum. This *must* be a genuine Vendor ID
+			to avoid polluting the USB namespace.
+			- CONFIG_USBD_VENDORID 0xFFFF
+
+			CONFIG_USBD_PRODUCTID
+			Define this as the unique Product ID
+			for your device
+			- CONFIG_USBD_PRODUCTID 0xFFFF
 
 
 - MMC Support:
@@ -2426,34 +2387,7 @@ is done by typing:
 	make NAME_config
 
 where "NAME_config" is the name of one of the existing
-configurations; the following names are supported:
-
-	ADCIOP_config		FPS860L_config		omap730p2_config
-	ADS860_config		GEN860T_config		pcu_e_config
-	Alaska8220_config
-	AR405_config		GENIETV_config		PIP405_config
-	at91rm9200dk_config	GTH_config		QS823_config
-	CANBT_config		hermes_config		QS850_config
-	cmi_mpc5xx_config	hymod_config		QS860T_config
-	cogent_common_config	IP860_config		RPXlite_config
-	cogent_mpc8260_config	IVML24_config		RPXlite_DW_config
-	cogent_mpc8xx_config	IVMS8_config		RPXsuper_config
-	CPCI405_config		JSE_config		rsdproto_config
-	CPCIISER4_config	LANTEC_config		Sandpoint8240_config
-	csb272_config		lwmon_config		sbc8260_config
-	CU824_config		MBX860T_config		sbc8560_33_config
-	DUET_ADS_config		MBX_config		sbc8560_66_config
-	EBONY_config		mpc7448hpc2_config	SM850_config
-	ELPT860_config		MPC8260ADS_config	SPD823TS_config
-	ESTEEM192E_config	MPC8540ADS_config	stxgp3_config
-	ETX094_config		MPC8540EVAL_config	SXNI855T_config
-	FADS823_config		NMPC8560ADS_config	TQM823L_config
-	FADS850SAR_config	NETVIA_config		TQM850L_config
-	FADS860T_config		omap1510inn_config	TQM855L_config
-	FPS850L_config		omap1610h2_config	TQM860L_config
-				omap1610inn_config	walnut_config
-				omap5912osk_config	Yukon8220_config
-				omap2420h4_config	ZPC1900_config
+configurations; see the main Makefile for supported names.
 
 Note: for some board special configuration names may exist; check if
       additional information is available from the board vendor; for
diff --git a/board/davinci/dv-evm/Makefile b/board/davinci/dv-evm/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..fa0013811d43f7e33a1d073c29cd7c02b1547a23
--- /dev/null
+++ b/board/davinci/dv-evm/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).a
+
+COBJS	:= dv_board.o
+SOBJS	:= board_init.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak *~ .depend
+
+#########################################################################
+# This is for $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/davinci/dv-evm/board_init.S b/board/davinci/dv-evm/board_init.S
new file mode 100644
index 0000000000000000000000000000000000000000..22d8adc18ca305d36eea2a29dacf21e952b8d0be
--- /dev/null
+++ b/board/davinci/dv-evm/board_init.S
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Board-specific low level initialization code. Called at the very end
+ * of cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no
+ * initialization required.
+ *
+ * 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 <config.h>
+
+.globl	dv_board_init
+dv_board_init:
+
+	mov	pc, lr
diff --git a/board/davinci/dv-evm/config.mk b/board/davinci/dv-evm/config.mk
new file mode 100644
index 0000000000000000000000000000000000000000..aa89d0ec8ae12bea17d271297589d242ab81c1d8
--- /dev/null
+++ b/board/davinci/dv-evm/config.mk
@@ -0,0 +1,39 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+#
+# (C) Copyright 2003
+# Texas Instruments, <www.ti.com>
+# Swaminathan <swami.iyer@ti.com>
+#
+# Davinci EVM board (ARM925EJS) cpu
+# see http://www.ti.com/ for more information on Texas Instruments
+#
+# Davinci EVM has 1 bank of 256 MB DDR RAM
+# Physical Address:
+# 8000'0000 to 9000'0000
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+#
+# Visioneering Corp. Sonata board (ARM926EJS) cpu
+#
+# Sonata board has 1 bank of 128 MB DDR RAM
+# Physical Address:
+# 8000'0000 to 8800'0000
+#
+# Razorstream, LLC. SCHMOOGIE board (ARM926EJS) cpu
+#
+# Schmoogie board has 1 bank of 128 MB DDR RAM
+# Physical Address:
+# 8000'0000 to 8800'0000
+#
+# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000
+# (mem base + reserved)
+#
+# we load ourself to 8108 '0000
+#
+#
+
+#Provide at least 16MB spacing between us and the Linux Kernel image
+TEXT_BASE = 0x81080000
diff --git a/board/davinci/dv-evm/dv_board.c b/board/davinci/dv-evm/dv_board.c
new file mode 100644
index 0000000000000000000000000000000000000000..94925ecfb14ace349c9148177008cb6e653097d8
--- /dev/null
+++ b/board/davinci/dv-evm/dv_board.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Parts are shamelessly stolen from various TI sources, original copyright
+ * follows:
+ * -----------------------------------------------------------------
+ *
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/emac_defs.h>
+
+#define MACH_TYPE_DAVINCI_EVM		901
+
+extern void	i2c_init(int speed, int slaveaddr);
+extern void	timer_init(void);
+extern int	eth_hw_init(void);
+extern phy_t	phy;
+
+
+/* Works on Always On power domain only (no PD argument) */
+void lpsc_on(unsigned int id)
+{
+	dv_reg_p	mdstat, mdctl;
+
+	if (id >= DAVINCI_LPSC_GEM)
+		return;			/* Don't work on DSP Power Domain */
+
+	mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4));
+	mdctl = REG_P(PSC_MDCTL_BASE + (id * 4));
+
+	while (REG(PSC_PTSTAT) & 0x01) {;}
+
+	if ((*mdstat & 0x1f) == 0x03)
+		return;			/* Already on and enabled */
+
+	*mdctl |= 0x03;
+
+	/* Special treatment for some modules as for sprue14 p.7.4.2 */
+	if (	(id == DAVINCI_LPSC_VPSSSLV) ||
+		(id == DAVINCI_LPSC_EMAC) ||
+		(id == DAVINCI_LPSC_EMAC_WRAPPER) ||
+		(id == DAVINCI_LPSC_MDIO) ||
+		(id == DAVINCI_LPSC_USB) ||
+		(id == DAVINCI_LPSC_ATA) ||
+		(id == DAVINCI_LPSC_VLYNQ) ||
+		(id == DAVINCI_LPSC_UHPI) ||
+		(id == DAVINCI_LPSC_DDR_EMIF) ||
+		(id == DAVINCI_LPSC_AEMIF) ||
+		(id == DAVINCI_LPSC_MMC_SD) ||
+		(id == DAVINCI_LPSC_MEMSTICK) ||
+		(id == DAVINCI_LPSC_McBSP) ||
+		(id == DAVINCI_LPSC_GPIO)
+	   )
+	   	*mdctl |= 0x200;
+
+	REG(PSC_PTCMD) = 0x01;
+
+	while (REG(PSC_PTSTAT) & 0x03) {;}
+	while ((*mdstat & 0x1f) != 0x03) {;}	/* Probably an overkill... */
+}
+
+void dsp_on(void)
+{
+	int	i;
+
+	if (REG(PSC_PDSTAT1) & 0x1f)
+		return;			/* Already on */
+
+	REG(PSC_GBLCTL) |= 0x01;
+	REG(PSC_PDCTL1) |= 0x01;
+	REG(PSC_PDCTL1) &= ~0x100;
+	REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03;
+	REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff;
+	REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03;
+	REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff;
+	REG(PSC_PTCMD) = 0x02;
+
+	for (i = 0; i < 100; i++) {
+		if (REG(PSC_EPCPR) & 0x02)
+			break;
+	}
+
+	REG(PSC_CHP_SHRTSW) = 0x01;
+	REG(PSC_PDCTL1) |= 0x100;
+	REG(PSC_EPCCR) = 0x02;
+
+	for (i = 0; i < 100; i++) {
+		if (!(REG(PSC_PTSTAT) & 0x02))
+			break;
+	}
+
+	REG(PSC_GBLCTL) &= ~0x1f;
+}
+
+
+int board_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* arch number of the board */
+	gd->bd->bi_arch_number = MACH_TYPE_DAVINCI_EVM;
+
+	/* address of boot parameters */
+	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
+
+	/* Workaround for TMS320DM6446 errata 1.3.22 */
+	REG(PSC_SILVER_BULLET) = 0;
+
+	/* Power on required peripherals */
+	lpsc_on(DAVINCI_LPSC_EMAC);
+	lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER);
+	lpsc_on(DAVINCI_LPSC_MDIO);
+	lpsc_on(DAVINCI_LPSC_I2C);
+	lpsc_on(DAVINCI_LPSC_UART0);
+	lpsc_on(DAVINCI_LPSC_TIMER1);
+	lpsc_on(DAVINCI_LPSC_GPIO);
+
+	/* Powerup the DSP */
+	dsp_on();
+
+	/* Bringup UART0 out of reset */
+	REG(UART0_PWREMU_MGMT) = 0x0000e003;
+
+	/* Enable GIO3.3V cells used for EMAC */
+	REG(VDD3P3V_PWDN) = 0;
+
+	/* Enable UART0 MUX lines */
+	REG(PINMUX1) |= 1;
+
+	/* Enable EMAC and AEMIF pins */
+	REG(PINMUX0) = 0x80000c1f;
+
+	/* Enable I2C pin Mux */
+	REG(PINMUX1) |= (1 << 7);
+
+	/* Set the Bus Priority Register to appropriate value */
+	REG(VBPR) = 0x20;
+
+	timer_init();
+
+	return(0);
+}
+
+int misc_init_r (void)
+{
+	u_int8_t	tmp[20], buf[10];
+	int		i = 0;
+	int		clk = 0;
+
+	clk = ((REG(PLL2_PLLM) + 1) * 27) / ((REG(PLL2_DIV2) & 0x1f) + 1);
+
+	printf ("ARM Clock : %dMHz\n", ((REG(PLL1_PLLM) + 1) * 27 ) / 2);
+	printf ("DDR Clock : %dMHz\n", (clk / 2));
+
+	/* Set Ethernet MAC address from EEPROM */
+	if (i2c_read(CFG_I2C_EEPROM_ADDR, 0x7f00, CFG_I2C_EEPROM_ADDR_LEN, buf, 6)) {
+		printf("\nEEPROM @ 0x%02x read FAILED!!!\n", CFG_I2C_EEPROM_ADDR);
+	} else {
+		tmp[0] = 0xff;
+		for (i = 0; i < 6; i++)
+			tmp[0] &= buf[i];
+
+		if ((tmp[0] != 0xff) && (getenv("ethaddr") == NULL)) {
+			sprintf((char *)&tmp[0], "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+				buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+			setenv("ethaddr", (char *)&tmp[0]);
+		}
+	}
+
+	if (!eth_hw_init()) {
+		printf("ethernet init failed!\n");
+	} else {
+		printf("ETH PHY   : %s\n", phy.name);
+	}
+
+	i2c_read (0x39, 0x00, 1, (u_int8_t *)&i, 1);
+
+	setenv ("videostd", ((i  & 0x80) ? "pal" : "ntsc"));
+
+	return(0);
+}
+
+int dram_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+	return(0);
+}
diff --git a/board/davinci/dv-evm/u-boot.lds b/board/davinci/dv-evm/u-boot.lds
new file mode 100644
index 0000000000000000000000000000000000000000..710b2a2d6e60df7b2ed55352a92a537654f4863e
--- /dev/null
+++ b/board/davinci/dv-evm/u-boot.lds
@@ -0,0 +1,52 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+	. = ALIGN(4);
+	.text	:
+	{
+	  cpu/arm926ejs/start.o	(.text)
+	  *(.text)
+	}
+	. = ALIGN(4);
+	.rodata : { *(.rodata) }
+	. = ALIGN(4);
+	.data : { *(.data) }
+	. = ALIGN(4);
+	.got : { *(.got) }
+
+	. = .;
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	__u_boot_cmd_end = .;
+
+	. = ALIGN(4);
+	__bss_start = .;
+	.bss : { *(.bss) }
+	_end = .;
+}
diff --git a/board/davinci/schmoogie/Makefile b/board/davinci/schmoogie/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..fa0013811d43f7e33a1d073c29cd7c02b1547a23
--- /dev/null
+++ b/board/davinci/schmoogie/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).a
+
+COBJS	:= dv_board.o
+SOBJS	:= board_init.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak *~ .depend
+
+#########################################################################
+# This is for $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/davinci/schmoogie/board_init.S b/board/davinci/schmoogie/board_init.S
new file mode 100644
index 0000000000000000000000000000000000000000..22d8adc18ca305d36eea2a29dacf21e952b8d0be
--- /dev/null
+++ b/board/davinci/schmoogie/board_init.S
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Board-specific low level initialization code. Called at the very end
+ * of cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no
+ * initialization required.
+ *
+ * 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 <config.h>
+
+.globl	dv_board_init
+dv_board_init:
+
+	mov	pc, lr
diff --git a/board/davinci/schmoogie/config.mk b/board/davinci/schmoogie/config.mk
new file mode 100644
index 0000000000000000000000000000000000000000..aa89d0ec8ae12bea17d271297589d242ab81c1d8
--- /dev/null
+++ b/board/davinci/schmoogie/config.mk
@@ -0,0 +1,39 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+#
+# (C) Copyright 2003
+# Texas Instruments, <www.ti.com>
+# Swaminathan <swami.iyer@ti.com>
+#
+# Davinci EVM board (ARM925EJS) cpu
+# see http://www.ti.com/ for more information on Texas Instruments
+#
+# Davinci EVM has 1 bank of 256 MB DDR RAM
+# Physical Address:
+# 8000'0000 to 9000'0000
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+#
+# Visioneering Corp. Sonata board (ARM926EJS) cpu
+#
+# Sonata board has 1 bank of 128 MB DDR RAM
+# Physical Address:
+# 8000'0000 to 8800'0000
+#
+# Razorstream, LLC. SCHMOOGIE board (ARM926EJS) cpu
+#
+# Schmoogie board has 1 bank of 128 MB DDR RAM
+# Physical Address:
+# 8000'0000 to 8800'0000
+#
+# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000
+# (mem base + reserved)
+#
+# we load ourself to 8108 '0000
+#
+#
+
+#Provide at least 16MB spacing between us and the Linux Kernel image
+TEXT_BASE = 0x81080000
diff --git a/board/davinci/schmoogie/dv_board.c b/board/davinci/schmoogie/dv_board.c
new file mode 100644
index 0000000000000000000000000000000000000000..b15c5f71893469a618aabf1bc952a5c33375dc02
--- /dev/null
+++ b/board/davinci/schmoogie/dv_board.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Parts are shamelessly stolen from various TI sources, original copyright
+ * follows:
+ * -----------------------------------------------------------------
+ *
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/emac_defs.h>
+
+#define MACH_TYPE_SCHMOOGIE		1255
+
+extern void	i2c_init(int speed, int slaveaddr);
+extern void	timer_init(void);
+extern int	eth_hw_init(void);
+extern phy_t	phy;
+
+
+/* Works on Always On power domain only (no PD argument) */
+void lpsc_on(unsigned int id)
+{
+	dv_reg_p	mdstat, mdctl;
+
+	if (id >= DAVINCI_LPSC_GEM)
+		return;			/* Don't work on DSP Power Domain */
+
+	mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4));
+	mdctl = REG_P(PSC_MDCTL_BASE + (id * 4));
+
+	while (REG(PSC_PTSTAT) & 0x01) {;}
+
+	if ((*mdstat & 0x1f) == 0x03)
+		return;			/* Already on and enabled */
+
+	*mdctl |= 0x03;
+
+	/* Special treatment for some modules as for sprue14 p.7.4.2 */
+	if (	(id == DAVINCI_LPSC_VPSSSLV) ||
+		(id == DAVINCI_LPSC_EMAC) ||
+		(id == DAVINCI_LPSC_EMAC_WRAPPER) ||
+		(id == DAVINCI_LPSC_MDIO) ||
+		(id == DAVINCI_LPSC_USB) ||
+		(id == DAVINCI_LPSC_ATA) ||
+		(id == DAVINCI_LPSC_VLYNQ) ||
+		(id == DAVINCI_LPSC_UHPI) ||
+		(id == DAVINCI_LPSC_DDR_EMIF) ||
+		(id == DAVINCI_LPSC_AEMIF) ||
+		(id == DAVINCI_LPSC_MMC_SD) ||
+		(id == DAVINCI_LPSC_MEMSTICK) ||
+		(id == DAVINCI_LPSC_McBSP) ||
+		(id == DAVINCI_LPSC_GPIO)
+	   )
+	   	*mdctl |= 0x200;
+
+	REG(PSC_PTCMD) = 0x01;
+
+	while (REG(PSC_PTSTAT) & 0x03) {;}
+	while ((*mdstat & 0x1f) != 0x03) {;}	/* Probably an overkill... */
+}
+
+void dsp_on(void)
+{
+	int	i;
+
+	if (REG(PSC_PDSTAT1) & 0x1f)
+		return;			/* Already on */
+
+	REG(PSC_GBLCTL) |= 0x01;
+	REG(PSC_PDCTL1) |= 0x01;
+	REG(PSC_PDCTL1) &= ~0x100;
+	REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03;
+	REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff;
+	REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03;
+	REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff;
+	REG(PSC_PTCMD) = 0x02;
+
+	for (i = 0; i < 100; i++) {
+		if (REG(PSC_EPCPR) & 0x02)
+			break;
+	}
+
+	REG(PSC_CHP_SHRTSW) = 0x01;
+	REG(PSC_PDCTL1) |= 0x100;
+	REG(PSC_EPCCR) = 0x02;
+
+	for (i = 0; i < 100; i++) {
+		if (!(REG(PSC_PTSTAT) & 0x02))
+			break;
+	}
+
+	REG(PSC_GBLCTL) &= ~0x1f;
+}
+
+
+int board_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* arch number of the board */
+	gd->bd->bi_arch_number = MACH_TYPE_SCHMOOGIE;
+
+	/* address of boot parameters */
+	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
+
+	/* Workaround for TMS320DM6446 errata 1.3.22 */
+	REG(PSC_SILVER_BULLET) = 0;
+
+	/* Power on required peripherals */
+	lpsc_on(DAVINCI_LPSC_EMAC);
+	lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER);
+	lpsc_on(DAVINCI_LPSC_MDIO);
+	lpsc_on(DAVINCI_LPSC_I2C);
+	lpsc_on(DAVINCI_LPSC_UART0);
+	lpsc_on(DAVINCI_LPSC_TIMER1);
+	lpsc_on(DAVINCI_LPSC_GPIO);
+
+	/* Powerup the DSP */
+	dsp_on();
+
+	/* Bringup UART0 out of reset */
+	REG(UART0_PWREMU_MGMT) = 0x0000e003;
+
+	/* Enable GIO3.3V cells used for EMAC */
+	REG(VDD3P3V_PWDN) = 0;
+
+	/* Enable UART0 MUX lines */
+	REG(PINMUX1) |= 1;
+
+	/* Enable EMAC and AEMIF pins */
+	REG(PINMUX0) = 0x80000c1f;
+
+	/* Enable I2C pin Mux */
+	REG(PINMUX1) |= (1 << 7);
+
+	/* Set the Bus Priority Register to appropriate value */
+	REG(VBPR) = 0x20;
+
+	timer_init();
+
+	return(0);
+}
+
+int misc_init_r (void)
+{
+	u_int8_t	tmp[20], buf[10];
+	int		i = 0;
+	int		clk = 0;
+
+	/* Set serial number from UID chip */
+	u_int8_t	crc_tbl[256] = {
+			0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
+			0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,
+			0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e,
+			0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc,
+			0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0,
+			0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62,
+			0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d,
+			0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,
+			0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5,
+			0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07,
+			0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58,
+			0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
+			0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6,
+			0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24,
+			0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b,
+			0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9,
+			0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f,
+			0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
+			0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92,
+			0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50,
+			0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c,
+			0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee,
+			0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1,
+			0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73,
+			0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49,
+			0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,
+			0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4,
+			0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16,
+			0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a,
+			0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8,
+			0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7,
+			0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35
+		};
+
+	clk = ((REG(PLL2_PLLM) + 1) * 27) / ((REG(PLL2_DIV2) & 0x1f) + 1);
+
+	printf ("ARM Clock : %dMHz\n", ((REG(PLL1_PLLM) + 1) * 27 ) / 2);
+	printf ("DDR Clock : %dMHz\n", (clk / 2));
+
+	/* Set serial number from UID chip */
+	if (i2c_read(CFG_UID_ADDR, 0, 1, buf, 8)) {
+		printf("\nUID @ 0x%02x read FAILED!!!\n", CFG_UID_ADDR);
+		forceenv("serial#", "FAILED");
+	} else {
+		if (buf[0] != 0x70) {	/* Device Family Code */
+			printf("\nUID @ 0x%02x read FAILED!!!\n", CFG_UID_ADDR);
+			forceenv("serial#", "FAILED");
+		}
+	}
+	/* Now check CRC */
+	tmp[0] = 0;
+	for (i = 0; i < 8; i++)
+		tmp[0] = crc_tbl[tmp[0] ^ buf[i]];
+
+	if (tmp[0] != 0) {
+		printf("\nUID @ 0x%02x - BAD CRC!!!\n", CFG_UID_ADDR);
+		forceenv("serial#", "FAILED");
+	} else {
+		/* CRC OK, set "serial" env variable */
+		sprintf((char *)&tmp[0], "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
+			buf[6], buf[5], buf[4], buf[3], buf[2], buf[1]);
+		forceenv("serial#", (char *)&tmp[0]);
+	}
+
+	if (!eth_hw_init()) {
+		printf("ethernet init failed!\n");
+	} else {
+		printf("ETH PHY   : %s\n", phy.name);
+	}
+
+	return(0);
+}
+
+int dram_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+	return(0);
+}
diff --git a/board/davinci/schmoogie/u-boot.lds b/board/davinci/schmoogie/u-boot.lds
new file mode 100644
index 0000000000000000000000000000000000000000..710b2a2d6e60df7b2ed55352a92a537654f4863e
--- /dev/null
+++ b/board/davinci/schmoogie/u-boot.lds
@@ -0,0 +1,52 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+	. = ALIGN(4);
+	.text	:
+	{
+	  cpu/arm926ejs/start.o	(.text)
+	  *(.text)
+	}
+	. = ALIGN(4);
+	.rodata : { *(.rodata) }
+	. = ALIGN(4);
+	.data : { *(.data) }
+	. = ALIGN(4);
+	.got : { *(.got) }
+
+	. = .;
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	__u_boot_cmd_end = .;
+
+	. = ALIGN(4);
+	__bss_start = .;
+	.bss : { *(.bss) }
+	_end = .;
+}
diff --git a/board/davinci/sonata/Makefile b/board/davinci/sonata/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..fa0013811d43f7e33a1d073c29cd7c02b1547a23
--- /dev/null
+++ b/board/davinci/sonata/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).a
+
+COBJS	:= dv_board.o
+SOBJS	:= board_init.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak *~ .depend
+
+#########################################################################
+# This is for $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/davinci/sonata/board_init.S b/board/davinci/sonata/board_init.S
new file mode 100644
index 0000000000000000000000000000000000000000..fbb9ea73e9fb723b3df00bfd886294c1e463dc7b
--- /dev/null
+++ b/board/davinci/sonata/board_init.S
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Board-specific low level initialization code. Called at the very end
+ * of cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no
+ * initialization required.
+ *
+ * For _OLDER_ Sonata boards sets up GPIO4 to control NAND WP line. Newer
+ * Sonata boards, AFAIK, don't use this so it's just return by default. Ask
+ * Visioneering if they reinvented the wheel once again to make sure :)
+ *
+ * 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 <config.h>
+
+.globl	dv_board_init
+dv_board_init:
+#ifdef SONATA_BOARD_GPIOWP
+	/* Set PINMUX0 to enable GPIO4 */
+	ldr	r0, _PINMUX0
+	ldr	r1, GPIO4_EN_MASK
+	ldr	r2, [r0]
+	and	r2, r2, r1
+	str	r2, [r0]
+
+	/* Enable GPIO LPSC module */
+	ldr	r0, PTSTAT
+
+gpio_ptstat_loop1:
+	ldr	r2, [r0]
+	tst	r2, $0x00000001
+	bne	gpio_ptstat_loop1
+
+	ldr	r1, MDCTL_GPIO
+	ldr	r2, [r1]
+	and	r2, r2, $0xfffffff8
+	orr	r2, r2, $0x00000003
+	str	r2, [r1]
+
+	orr	r2, r2, $0x00000200
+	str	r2, [r1]
+
+	ldr	r1, PTCMD
+	mov	r2, $0x00000001
+	str	r2, [r1]
+
+gpio_ptstat_loop2:
+	ldr	r2, [r0]
+	tst	r2, $0x00000001
+	bne	gpio_ptstat_loop2
+
+	ldr	r0, MDSTAT_GPIO
+gpio_mdstat_loop:
+	ldr	r2, [r0]
+	and	r2, r2, $0x0000001f
+	teq	r2, $0x00000003
+	bne	gpio_mdstat_loop
+
+	/* GPIO4 -> output */
+	ldr	r0, GPIO_DIR01
+	mov	r1, $0x10
+	ldr	r2, [r0]
+	bic	r2, r2, r0
+	str	r2, [r0]
+
+	/* Set it to 0 (Write Protect) */
+	ldr	r0, GPIO_CLR_DATA01
+	str	r1, [r0]
+#endif
+
+	mov	pc, lr
+
+#ifdef SONATA_BOARD_GPIOWP
+.ltorg
+
+GPIO4_EN_MASK:
+	.word	0xf77fffff
+MDCTL_GPIO:
+	.word	0x01c41a68
+MDSTAT_GPIO:
+	.word	0x01c41868
+GPIO_DIR01:
+	.word	0x01c67010
+GPIO_CLR_DATA01:
+	.word	0x01c6701c
+#endif
diff --git a/board/davinci/sonata/config.mk b/board/davinci/sonata/config.mk
new file mode 100644
index 0000000000000000000000000000000000000000..aa89d0ec8ae12bea17d271297589d242ab81c1d8
--- /dev/null
+++ b/board/davinci/sonata/config.mk
@@ -0,0 +1,39 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+#
+# (C) Copyright 2003
+# Texas Instruments, <www.ti.com>
+# Swaminathan <swami.iyer@ti.com>
+#
+# Davinci EVM board (ARM925EJS) cpu
+# see http://www.ti.com/ for more information on Texas Instruments
+#
+# Davinci EVM has 1 bank of 256 MB DDR RAM
+# Physical Address:
+# 8000'0000 to 9000'0000
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+#
+# Visioneering Corp. Sonata board (ARM926EJS) cpu
+#
+# Sonata board has 1 bank of 128 MB DDR RAM
+# Physical Address:
+# 8000'0000 to 8800'0000
+#
+# Razorstream, LLC. SCHMOOGIE board (ARM926EJS) cpu
+#
+# Schmoogie board has 1 bank of 128 MB DDR RAM
+# Physical Address:
+# 8000'0000 to 8800'0000
+#
+# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000
+# (mem base + reserved)
+#
+# we load ourself to 8108 '0000
+#
+#
+
+#Provide at least 16MB spacing between us and the Linux Kernel image
+TEXT_BASE = 0x81080000
diff --git a/board/davinci/sonata/dv_board.c b/board/davinci/sonata/dv_board.c
new file mode 100644
index 0000000000000000000000000000000000000000..7b0a459fa3198703f9a3fa150202aa5b314cd2ad
--- /dev/null
+++ b/board/davinci/sonata/dv_board.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Parts are shamelessly stolen from various TI sources, original copyright
+ * follows:
+ * -----------------------------------------------------------------
+ *
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/emac_defs.h>
+
+#define MACH_TYPE_SONATA		1254
+
+extern void	i2c_init(int speed, int slaveaddr);
+extern void	timer_init(void);
+extern int	eth_hw_init(void);
+extern phy_t	phy;
+
+
+/* Works on Always On power domain only (no PD argument) */
+void lpsc_on(unsigned int id)
+{
+	dv_reg_p	mdstat, mdctl;
+
+	if (id >= DAVINCI_LPSC_GEM)
+		return;			/* Don't work on DSP Power Domain */
+
+	mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4));
+	mdctl = REG_P(PSC_MDCTL_BASE + (id * 4));
+
+	while (REG(PSC_PTSTAT) & 0x01) {;}
+
+	if ((*mdstat & 0x1f) == 0x03)
+		return;			/* Already on and enabled */
+
+	*mdctl |= 0x03;
+
+	/* Special treatment for some modules as for sprue14 p.7.4.2 */
+	if (	(id == DAVINCI_LPSC_VPSSSLV) ||
+		(id == DAVINCI_LPSC_EMAC) ||
+		(id == DAVINCI_LPSC_EMAC_WRAPPER) ||
+		(id == DAVINCI_LPSC_MDIO) ||
+		(id == DAVINCI_LPSC_USB) ||
+		(id == DAVINCI_LPSC_ATA) ||
+		(id == DAVINCI_LPSC_VLYNQ) ||
+		(id == DAVINCI_LPSC_UHPI) ||
+		(id == DAVINCI_LPSC_DDR_EMIF) ||
+		(id == DAVINCI_LPSC_AEMIF) ||
+		(id == DAVINCI_LPSC_MMC_SD) ||
+		(id == DAVINCI_LPSC_MEMSTICK) ||
+		(id == DAVINCI_LPSC_McBSP) ||
+		(id == DAVINCI_LPSC_GPIO)
+	   )
+	   	*mdctl |= 0x200;
+
+	REG(PSC_PTCMD) = 0x01;
+
+	while (REG(PSC_PTSTAT) & 0x03) {;}
+	while ((*mdstat & 0x1f) != 0x03) {;}	/* Probably an overkill... */
+}
+
+void dsp_on(void)
+{
+	int	i;
+
+	if (REG(PSC_PDSTAT1) & 0x1f)
+		return;			/* Already on */
+
+	REG(PSC_GBLCTL) |= 0x01;
+	REG(PSC_PDCTL1) |= 0x01;
+	REG(PSC_PDCTL1) &= ~0x100;
+	REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03;
+	REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff;
+	REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03;
+	REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff;
+	REG(PSC_PTCMD) = 0x02;
+
+	for (i = 0; i < 100; i++) {
+		if (REG(PSC_EPCPR) & 0x02)
+			break;
+	}
+
+	REG(PSC_CHP_SHRTSW) = 0x01;
+	REG(PSC_PDCTL1) |= 0x100;
+	REG(PSC_EPCCR) = 0x02;
+
+	for (i = 0; i < 100; i++) {
+		if (!(REG(PSC_PTSTAT) & 0x02))
+			break;
+	}
+
+	REG(PSC_GBLCTL) &= ~0x1f;
+}
+
+
+int board_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* arch number of the board */
+	gd->bd->bi_arch_number = MACH_TYPE_SONATA;
+
+	/* address of boot parameters */
+	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
+
+	/* Workaround for TMS320DM6446 errata 1.3.22 */
+	REG(PSC_SILVER_BULLET) = 0;
+
+	/* Power on required peripherals */
+	lpsc_on(DAVINCI_LPSC_EMAC);
+	lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER);
+	lpsc_on(DAVINCI_LPSC_MDIO);
+	lpsc_on(DAVINCI_LPSC_I2C);
+	lpsc_on(DAVINCI_LPSC_UART0);
+	lpsc_on(DAVINCI_LPSC_TIMER1);
+	lpsc_on(DAVINCI_LPSC_GPIO);
+
+	/* Powerup the DSP */
+	dsp_on();
+
+	/* Bringup UART0 out of reset */
+	REG(UART0_PWREMU_MGMT) = 0x0000e003;
+
+	/* Enable GIO3.3V cells used for EMAC */
+	REG(VDD3P3V_PWDN) = 0;
+
+	/* Enable UART0 MUX lines */
+	REG(PINMUX1) |= 1;
+
+	/* Enable EMAC and AEMIF pins */
+	REG(PINMUX0) = 0x80000c1f;
+
+	/* Enable I2C pin Mux */
+	REG(PINMUX1) |= (1 << 7);
+
+	/* Set the Bus Priority Register to appropriate value */
+	REG(VBPR) = 0x20;
+
+	timer_init();
+
+	return(0);
+}
+
+int misc_init_r (void)
+{
+	u_int8_t	tmp[20], buf[10];
+	int		i = 0;
+	int		clk = 0;
+
+
+	clk = ((REG(PLL2_PLLM) + 1) * 27) / ((REG(PLL2_DIV2) & 0x1f) + 1);
+
+	printf ("ARM Clock : %dMHz\n", ((REG(PLL1_PLLM) + 1) * 27 ) / 2);
+	printf ("DDR Clock : %dMHz\n", (clk / 2));
+
+	/* Set Ethernet MAC address from EEPROM */
+	if (i2c_read(CFG_I2C_EEPROM_ADDR, 0x7f00, CFG_I2C_EEPROM_ADDR_LEN, buf, 6)) {
+		printf("\nEEPROM @ 0x%02x read FAILED!!!\n", CFG_I2C_EEPROM_ADDR);
+	} else {
+		tmp[0] = 0xff;
+		for (i = 0; i < 6; i++)
+			tmp[0] &= buf[i];
+
+		if ((tmp[0] != 0xff) && (getenv("ethaddr") == NULL)) {
+			sprintf((char *)&tmp[0], "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+				buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+			setenv("ethaddr", (char *)&tmp[0]);
+		}
+	}
+
+	if (!eth_hw_init()) {
+		printf("ethernet init failed!\n");
+	} else {
+		printf("ETH PHY   : %s\n", phy.name);
+	}
+
+	return(0);
+}
+
+int dram_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+	return(0);
+}
diff --git a/board/davinci/sonata/u-boot.lds b/board/davinci/sonata/u-boot.lds
new file mode 100644
index 0000000000000000000000000000000000000000..710b2a2d6e60df7b2ed55352a92a537654f4863e
--- /dev/null
+++ b/board/davinci/sonata/u-boot.lds
@@ -0,0 +1,52 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+	. = ALIGN(4);
+	.text	:
+	{
+	  cpu/arm926ejs/start.o	(.text)
+	  *(.text)
+	}
+	. = ALIGN(4);
+	.rodata : { *(.rodata) }
+	. = ALIGN(4);
+	.data : { *(.data) }
+	. = ALIGN(4);
+	.got : { *(.got) }
+
+	. = .;
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	__u_boot_cmd_end = .;
+
+	. = ALIGN(4);
+	__bss_start = .;
+	.bss : { *(.bss) }
+	_end = .;
+}
diff --git a/board/delta/delta.c b/board/delta/delta.c
index b127ac8cab7b1e9b5569c3618cdfb6ad9362a177..6e227748b0168bbc687fa07ba2bf86a6a2bb6b8f 100644
--- a/board/delta/delta.c
+++ b/board/delta/delta.c
@@ -1,10 +1,6 @@
 /*
- * (C) Copyright 2002
- * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
+ * (C) Copyright 2006
+ * DENX Software Engineering
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -98,7 +94,6 @@ int board_late_init(void)
 	return 0;
 }
 
-
 /*
  * Magic Key Handling, mainly copied from board/lwmon/lwmon.c
  */
@@ -324,6 +319,12 @@ static void init_DA9030()
 		return;
 	}
 
+	val = 0x80;
+	if(i2c_write(addr, IRQ_MASK_B, 1, &val, 1)) {
+		printf("Error accessing DA9030 via i2c.\n");
+		return;
+	}
+
 	i2c_reg_write(addr, REG_CONTROL_1_97, 0xfd); /* disable LDO1, enable LDO6 */
 	i2c_reg_write(addr, LDO2_3, 0xd1);	/* LDO2 =1,9V, LDO3=3,1V */
 	i2c_reg_write(addr, LDO4_5, 0xcc);	/* LDO2 =1,9V, LDO3=3,1V */
diff --git a/board/freescale/mpc8323erdb/Makefile b/board/freescale/mpc8323erdb/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..acc954488f54bdb8e0b99991dad67d2649b49a35
--- /dev/null
+++ b/board/freescale/mpc8323erdb/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).a
+
+COBJS	:= $(BOARD).o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/freescale/mpc8323erdb/config.mk b/board/freescale/mpc8323erdb/config.mk
new file mode 100644
index 0000000000000000000000000000000000000000..fe0d37d424eca3033ac873f039e83fe9fa284c61
--- /dev/null
+++ b/board/freescale/mpc8323erdb/config.mk
@@ -0,0 +1,28 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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
+#
+
+#
+# MPC8323ERDB
+#
+
+TEXT_BASE = 0xFE000000
diff --git a/board/freescale/mpc8323erdb/mpc8323erdb.c b/board/freescale/mpc8323erdb/mpc8323erdb.c
new file mode 100644
index 0000000000000000000000000000000000000000..1886f196b27d8bcd2e92cd0c1df913606c19a811
--- /dev/null
+++ b/board/freescale/mpc8323erdb/mpc8323erdb.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2007 Freescale Semiconductor, Inc.
+ *
+ * Michael Barkowski <michael.barkowski@freescale.com>
+ * Based on mpc832xmds file by Dave Liu <daveliu@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <ioports.h>
+#include <mpc83xx.h>
+#include <i2c.h>
+#include <spd.h>
+#include <miiphy.h>
+#include <command.h>
+#include <libfdt.h>
+#include <libfdt_env.h>
+#if defined(CONFIG_PCI)
+#include <pci.h>
+#endif
+#if defined(CONFIG_SPD_EEPROM)
+#include <spd_sdram.h>
+#else
+#include <asm/mmu.h>
+#endif
+
+const qe_iop_conf_t qe_iop_conf_tab[] = {
+	/* UCC3 */
+	{1,  0, 1, 0, 1}, /* TxD0 */
+	{1,  1, 1, 0, 1}, /* TxD1 */
+	{1,  2, 1, 0, 1}, /* TxD2 */
+	{1,  3, 1, 0, 1}, /* TxD3 */
+	{1,  9, 1, 0, 1}, /* TxER */
+	{1, 12, 1, 0, 1}, /* TxEN */
+	{3, 24, 2, 0, 1}, /* TxCLK->CLK10 */
+
+	{1,  4, 2, 0, 1}, /* RxD0 */
+	{1,  5, 2, 0, 1}, /* RxD1 */
+	{1,  6, 2, 0, 1}, /* RxD2 */
+	{1,  7, 2, 0, 1}, /* RxD3 */
+	{1,  8, 2, 0, 1}, /* RxER */
+	{1, 10, 2, 0, 1}, /* RxDV */
+	{0, 13, 2, 0, 1}, /* RxCLK->CLK9 */
+	{1, 11, 2, 0, 1}, /* COL */
+	{1, 13, 2, 0, 1}, /* CRS */
+
+	/* UCC2 */
+	{0, 18, 1, 0, 1}, /* TxD0 */
+	{0, 19, 1, 0, 1}, /* TxD1 */
+	{0, 20, 1, 0, 1}, /* TxD2 */
+	{0, 21, 1, 0, 1}, /* TxD3 */
+	{0, 27, 1, 0, 1}, /* TxER */
+	{0, 30, 1, 0, 1}, /* TxEN */
+	{3, 23, 2, 0, 1}, /* TxCLK->CLK3 */
+
+	{0, 22, 2, 0, 1}, /* RxD0 */
+	{0, 23, 2, 0, 1}, /* RxD1 */
+	{0, 24, 2, 0, 1}, /* RxD2 */
+	{0, 25, 2, 0, 1}, /* RxD3 */
+	{0, 26, 1, 0, 1}, /* RxER */
+	{0, 28, 2, 0, 1}, /* Rx_DV */
+	{3, 21, 2, 0, 1}, /* RxCLK->CLK16 */
+	{0, 29, 2, 0, 1}, /* COL */
+	{0, 31, 2, 0, 1}, /* CRS */
+
+	{3,  4, 3, 0, 2}, /* MDIO */
+	{3,  5, 1, 0, 2}, /* MDC */
+
+	{0,  0, 0, 0, QE_IOP_TAB_END}, /* END of table */
+};
+
+int board_early_init_f(void)
+{
+	return 0;
+}
+
+int fixed_sdram(void);
+
+long int initdram(int board_type)
+{
+	volatile immap_t *im = (immap_t *) CFG_IMMR;
+	u32 msize = 0;
+
+	if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
+		return -1;
+
+	/* DDR SDRAM - Main SODIMM */
+	im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR;
+
+	msize = fixed_sdram();
+
+	puts("\n   DDR RAM: ");
+
+	/* return total bus SDRAM size(bytes)  -- DDR */
+	return (msize * 1024 * 1024);
+}
+
+/*************************************************************************
+ *  fixed sdram init -- doesn't use serial presence detect.
+ ************************************************************************/
+int fixed_sdram(void)
+{
+	volatile immap_t *im = (immap_t *) CFG_IMMR;
+	u32 msize = 0;
+	u32 ddr_size;
+	u32 ddr_size_log2;
+
+	msize = CFG_DDR_SIZE;
+	for (ddr_size = msize << 20, ddr_size_log2 = 0;
+	     (ddr_size > 1); ddr_size = ddr_size >> 1, ddr_size_log2++) {
+		if (ddr_size & 1) {
+			return -1;
+		}
+	}
+	im->sysconf.ddrlaw[0].ar =
+	    LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE);
+	im->ddr.sdram_clk_cntl = CFG_DDR_CLK_CNTL;
+	im->ddr.csbnds[0].csbnds = CFG_DDR_CS0_BNDS;
+	im->ddr.cs_config[0] = CFG_DDR_CS0_CONFIG;
+	im->ddr.timing_cfg_0 = CFG_DDR_TIMING_0;
+	im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1;
+	im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;
+	im->ddr.timing_cfg_3 = CFG_DDR_TIMING_3;
+	im->ddr.sdram_cfg = CFG_DDR_SDRAM_CFG;
+	im->ddr.sdram_cfg2 = CFG_DDR_SDRAM_CFG2;
+	im->ddr.sdram_mode = CFG_DDR_MODE;
+	im->ddr.sdram_mode2 = CFG_DDR_MODE2;
+	im->ddr.sdram_interval = CFG_DDR_INTERVAL;
+	__asm__ __volatile__ ("sync");
+	udelay(200);
+
+	im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
+	__asm__ __volatile__ ("sync");
+	return msize;
+}
+
+int checkboard(void)
+{
+	puts("Board: Freescale MPC8323ERDB\n");
+	return 0;
+}
+
+static struct pci_region pci_regions[] = {
+	{
+		bus_start: CFG_PCI1_MEM_BASE,
+		phys_start: CFG_PCI1_MEM_PHYS,
+		size: CFG_PCI1_MEM_SIZE,
+		flags: PCI_REGION_MEM | PCI_REGION_PREFETCH
+	},
+	{
+		bus_start: CFG_PCI1_MMIO_BASE,
+		phys_start: CFG_PCI1_MMIO_PHYS,
+		size: CFG_PCI1_MMIO_SIZE,
+		flags: PCI_REGION_MEM
+	},
+	{
+		bus_start: CFG_PCI1_IO_BASE,
+		phys_start: CFG_PCI1_IO_PHYS,
+		size: CFG_PCI1_IO_SIZE,
+		flags: PCI_REGION_IO
+	}
+};
+
+void pci_init_board(void)
+{
+	volatile immap_t *immr = (volatile immap_t *)CFG_IMMR;
+	volatile clk83xx_t *clk = (volatile clk83xx_t *)&immr->clk;
+	volatile law83xx_t *pci_law = immr->sysconf.pcilaw;
+	struct pci_region *reg[] = { pci_regions };
+
+	/* Enable all 3 PCI_CLK_OUTPUTs. */
+	clk->occr |= 0xe0000000;
+
+	/* Configure PCI Local Access Windows */
+	pci_law[0].bar = CFG_PCI1_MEM_PHYS & LAWBAR_BAR;
+	pci_law[0].ar = LBLAWAR_EN | LBLAWAR_512MB;
+
+	pci_law[1].bar = CFG_PCI1_IO_PHYS & LAWBAR_BAR;
+	pci_law[1].ar = LBLAWAR_EN | LBLAWAR_1MB;
+
+	mpc83xx_pci_init(1, reg, 0);
+}
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+
+/*
+ * Prototypes of functions that we use.
+ */
+void ft_cpu_setup(void *blob, bd_t *bd);
+
+#ifdef CONFIG_PCI
+void ft_pci_setup(void *blob, bd_t *bd);
+#endif
+
+void
+ft_board_setup(void *blob, bd_t *bd)
+{
+	int nodeoffset;
+	int tmp[2];
+
+	nodeoffset = fdt_find_node_by_path(blob, "/memory");
+	if (nodeoffset >= 0) {
+		tmp[0] = cpu_to_be32(bd->bi_memstart);
+		tmp[1] = cpu_to_be32(bd->bi_memsize);
+		fdt_setprop(blob, nodeoffset, "reg", tmp, sizeof(tmp));
+	}
+
+	ft_cpu_setup(blob, bd);
+
+#ifdef CONFIG_PCI
+	ft_pci_setup(blob, bd);
+#endif
+}
+#endif /* CONFIG_OF_BOARD_SETUP */
diff --git a/board/mpc8349emds/mpc8349emds.c b/board/mpc8349emds/mpc8349emds.c
index 071591ed8356fc0de728812a5744dceb998d268b..521d1bbd4ed752b8f9434ce028ec1fd208b78533 100644
--- a/board/mpc8349emds/mpc8349emds.c
+++ b/board/mpc8349emds/mpc8349emds.c
@@ -29,7 +29,6 @@
 #include <i2c.h>
 #include <spd.h>
 #include <miiphy.h>
-#include <command.h>
 #if defined(CONFIG_SPD_EEPROM)
 #include <spd_sdram.h>
 #endif
@@ -258,332 +257,6 @@ void sdram_init(void)
 }
 #endif
 
-#if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD)
-/*
- * ECC user commands
- */
-void ecc_print_status(void)
-{
-	volatile immap_t *immap = (immap_t *)CFG_IMMR;
-	volatile ddr83xx_t *ddr = &immap->ddr;
-
-	printf("\nECC mode: %s\n\n", (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF");
-
-	/* Interrupts */
-	printf("Memory Error Interrupt Enable:\n");
-	printf("  Multiple-Bit Error Interrupt Enable: %d\n",
-			(ddr->err_int_en & ECC_ERR_INT_EN_MBEE) ? 1 : 0);
-	printf("  Single-Bit Error Interrupt Enable: %d\n",
-			(ddr->err_int_en & ECC_ERR_INT_EN_SBEE) ? 1 : 0);
-	printf("  Memory Select Error Interrupt Enable: %d\n\n",
-			(ddr->err_int_en & ECC_ERR_INT_EN_MSEE) ? 1 : 0);
-
-	/* Error disable */
-	printf("Memory Error Disable:\n");
-	printf("  Multiple-Bit Error Disable: %d\n",
-			(ddr->err_disable & ECC_ERROR_DISABLE_MBED) ? 1 : 0);
-	printf("  Sinle-Bit Error Disable: %d\n",
-			(ddr->err_disable & ECC_ERROR_DISABLE_SBED) ? 1 : 0);
-	printf("  Memory Select Error Disable: %d\n\n",
-			(ddr->err_disable & ECC_ERROR_DISABLE_MSED) ? 1 : 0);
-
-	/* Error injection */
-	printf("Memory Data Path Error Injection Mask High/Low: %08lx %08lx\n",
-			ddr->data_err_inject_hi, ddr->data_err_inject_lo);
-
-	printf("Memory Data Path Error Injection Mask ECC:\n");
-	printf("  ECC Mirror Byte: %d\n",
-			(ddr->ecc_err_inject & ECC_ERR_INJECT_EMB) ? 1 : 0);
-	printf("  ECC Injection Enable: %d\n",
-			(ddr->ecc_err_inject & ECC_ERR_INJECT_EIEN) ? 1 : 0);
-	printf("  ECC Error Injection Mask: 0x%02x\n\n",
-			ddr->ecc_err_inject & ECC_ERR_INJECT_EEIM);
-
-	/* SBE counter/threshold */
-	printf("Memory Single-Bit Error Management (0..255):\n");
-	printf("  Single-Bit Error Threshold: %d\n",
-			(ddr->err_sbe & ECC_ERROR_MAN_SBET) >> ECC_ERROR_MAN_SBET_SHIFT);
-	printf("  Single-Bit Error Counter: %d\n\n",
-			(ddr->err_sbe & ECC_ERROR_MAN_SBEC) >> ECC_ERROR_MAN_SBEC_SHIFT);
-
-	/* Error detect */
-	printf("Memory Error Detect:\n");
-	printf("  Multiple Memory Errors: %d\n",
-			(ddr->err_detect & ECC_ERROR_DETECT_MME) ? 1 : 0);
-	printf("  Multiple-Bit Error: %d\n",
-			(ddr->err_detect & ECC_ERROR_DETECT_MBE) ? 1 : 0);
-	printf("  Single-Bit Error: %d\n",
-			(ddr->err_detect & ECC_ERROR_DETECT_SBE) ? 1 : 0);
-	printf("  Memory Select Error: %d\n\n",
-			(ddr->err_detect & ECC_ERROR_DETECT_MSE) ? 1 : 0);
-
-	/* Capture data */
-	printf("Memory Error Address Capture: 0x%08lx\n", ddr->capture_address);
-	printf("Memory Data Path Read Capture High/Low: %08lx %08lx\n",
-			ddr->capture_data_hi, ddr->capture_data_lo);
-	printf("Memory Data Path Read Capture ECC: 0x%02x\n\n",
-		ddr->capture_ecc & CAPTURE_ECC_ECE);
-
-	printf("Memory Error Attributes Capture:\n");
-	printf("  Data Beat Number: %d\n",
-			(ddr->capture_attributes & ECC_CAPT_ATTR_BNUM) >> ECC_CAPT_ATTR_BNUM_SHIFT);
-	printf("  Transaction Size: %d\n",
-			(ddr->capture_attributes & ECC_CAPT_ATTR_TSIZ) >> ECC_CAPT_ATTR_TSIZ_SHIFT);
-	printf("  Transaction Source: %d\n",
-			(ddr->capture_attributes & ECC_CAPT_ATTR_TSRC) >> ECC_CAPT_ATTR_TSRC_SHIFT);
-	printf("  Transaction Type: %d\n",
-			(ddr->capture_attributes & ECC_CAPT_ATTR_TTYP) >> ECC_CAPT_ATTR_TTYP_SHIFT);
-	printf("  Error Information Valid: %d\n\n",
-			ddr->capture_attributes & ECC_CAPT_ATTR_VLD);
-}
-
-int do_ecc ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-{
-	volatile immap_t *immap = (immap_t *)CFG_IMMR;
-	volatile ddr83xx_t *ddr = &immap->ddr;
-	volatile u32 val;
-	u64 *addr, count, val64;
-	register u64 *i;
-
-	if (argc > 4) {
-		printf ("Usage:\n%s\n", cmdtp->usage);
-		return 1;
-	}
-
-	if (argc == 2) {
-		if (strcmp(argv[1], "status") == 0) {
-			ecc_print_status();
-			return 0;
-		} else if (strcmp(argv[1], "captureclear") == 0) {
-			ddr->capture_address = 0;
-			ddr->capture_data_hi = 0;
-			ddr->capture_data_lo = 0;
-			ddr->capture_ecc = 0;
-			ddr->capture_attributes = 0;
-			return 0;
-		}
-	}
-
-	if (argc == 3) {
-		if (strcmp(argv[1], "sbecnt") == 0) {
-			val = simple_strtoul(argv[2], NULL, 10);
-			if (val > 255) {
-				printf("Incorrect Counter value, should be 0..255\n");
-				return 1;
-			}
-
-			val = (val << ECC_ERROR_MAN_SBEC_SHIFT);
-			val |= (ddr->err_sbe & ECC_ERROR_MAN_SBET);
-
-			ddr->err_sbe = val;
-			return 0;
-		} else if (strcmp(argv[1], "sbethr") == 0) {
-			val = simple_strtoul(argv[2], NULL, 10);
-			if (val > 255) {
-				printf("Incorrect Counter value, should be 0..255\n");
-				return 1;
-			}
-
-			val = (val << ECC_ERROR_MAN_SBET_SHIFT);
-			val |= (ddr->err_sbe & ECC_ERROR_MAN_SBEC);
-
-			ddr->err_sbe = val;
-			return 0;
-		} else if (strcmp(argv[1], "errdisable") == 0) {
-			val = ddr->err_disable;
-
-			if (strcmp(argv[2], "+sbe") == 0) {
-				val |= ECC_ERROR_DISABLE_SBED;
-			} else if (strcmp(argv[2], "+mbe") == 0) {
-				val |= ECC_ERROR_DISABLE_MBED;
-			} else if (strcmp(argv[2], "+mse") == 0) {
-				val |= ECC_ERROR_DISABLE_MSED;
-			} else if (strcmp(argv[2], "+all") == 0) {
-				val |= (ECC_ERROR_DISABLE_SBED |
-					ECC_ERROR_DISABLE_MBED |
-					ECC_ERROR_DISABLE_MSED);
-			} else if (strcmp(argv[2], "-sbe") == 0) {
-				val &= ~ECC_ERROR_DISABLE_SBED;
-			} else if (strcmp(argv[2], "-mbe") == 0) {
-				val &= ~ECC_ERROR_DISABLE_MBED;
-			} else if (strcmp(argv[2], "-mse") == 0) {
-				val &= ~ECC_ERROR_DISABLE_MSED;
-			} else if (strcmp(argv[2], "-all") == 0) {
-				val &= ~(ECC_ERROR_DISABLE_SBED |
-					ECC_ERROR_DISABLE_MBED |
-					ECC_ERROR_DISABLE_MSED);
-			} else {
-				printf("Incorrect err_disable field\n");
-				return 1;
-			}
-
-			ddr->err_disable = val;
-			__asm__ __volatile__ ("sync");
-			__asm__ __volatile__ ("isync");
-			return 0;
-		} else if (strcmp(argv[1], "errdetectclr") == 0) {
-			val = ddr->err_detect;
-
-			if (strcmp(argv[2], "mme") == 0) {
-				val |= ECC_ERROR_DETECT_MME;
-			} else if (strcmp(argv[2], "sbe") == 0) {
-				val |= ECC_ERROR_DETECT_SBE;
-			} else if (strcmp(argv[2], "mbe") == 0) {
-				val |= ECC_ERROR_DETECT_MBE;
-			} else if (strcmp(argv[2], "mse") == 0) {
-				val |= ECC_ERROR_DETECT_MSE;
-			} else if (strcmp(argv[2], "all") == 0) {
-				val |= (ECC_ERROR_DETECT_MME |
-					ECC_ERROR_DETECT_MBE |
-					ECC_ERROR_DETECT_SBE |
-					ECC_ERROR_DETECT_MSE);
-			} else {
-				printf("Incorrect err_detect field\n");
-				return 1;
-			}
-
-			ddr->err_detect = val;
-			return 0;
-		} else if (strcmp(argv[1], "injectdatahi") == 0) {
-			val = simple_strtoul(argv[2], NULL, 16);
-
-			ddr->data_err_inject_hi = val;
-			return 0;
-		} else if (strcmp(argv[1], "injectdatalo") == 0) {
-			val = simple_strtoul(argv[2], NULL, 16);
-
-			ddr->data_err_inject_lo = val;
-			return 0;
-		} else if (strcmp(argv[1], "injectecc") == 0) {
-			val = simple_strtoul(argv[2], NULL, 16);
-			if (val > 0xff) {
-				printf("Incorrect ECC inject mask, should be 0x00..0xff\n");
-				return 1;
-			}
-			val |= (ddr->ecc_err_inject & ~ECC_ERR_INJECT_EEIM);
-
-			ddr->ecc_err_inject = val;
-			return 0;
-		} else if (strcmp(argv[1], "inject") == 0) {
-			val = ddr->ecc_err_inject;
-
-			if (strcmp(argv[2], "en") == 0)
-				val |= ECC_ERR_INJECT_EIEN;
-			else if (strcmp(argv[2], "dis") == 0)
-				val &= ~ECC_ERR_INJECT_EIEN;
-			else
-				printf("Incorrect command\n");
-
-			ddr->ecc_err_inject = val;
-			__asm__ __volatile__ ("sync");
-			__asm__ __volatile__ ("isync");
-			return 0;
-		} else if (strcmp(argv[1], "mirror") == 0) {
-			val = ddr->ecc_err_inject;
-
-			if (strcmp(argv[2], "en") == 0)
-				val |= ECC_ERR_INJECT_EMB;
-			else if (strcmp(argv[2], "dis") == 0)
-				val &= ~ECC_ERR_INJECT_EMB;
-			else
-				printf("Incorrect command\n");
-
-			ddr->ecc_err_inject = val;
-			return 0;
-		}
-	}
-
-	if (argc == 4) {
-		if (strcmp(argv[1], "test") == 0) {
-			addr = (u64 *)simple_strtoul(argv[2], NULL, 16);
-			count = simple_strtoul(argv[3], NULL, 16);
-
-			if ((u32)addr % 8) {
-				printf("Address not alligned on double word boundary\n");
-				return 1;
-			}
-
-			disable_interrupts();
-			icache_disable();
-
-			for (i = addr; i < addr + count; i++) {
-				/* enable injects */
-				ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
-				__asm__ __volatile__ ("sync");
-				__asm__ __volatile__ ("isync");
-
-				/* write memory location injecting errors */
-				*i = 0x1122334455667788ULL;
-				__asm__ __volatile__ ("sync");
-
-				/* disable injects */
-				ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
-				__asm__ __volatile__ ("sync");
-				__asm__ __volatile__ ("isync");
-
-				/* read data, this generates ECC error */
-				val64 = *i;
-				__asm__ __volatile__ ("sync");
-
-				/* disable errors for ECC */
-				ddr->err_disable |= ~ECC_ERROR_ENABLE;
-				__asm__ __volatile__ ("sync");
-				__asm__ __volatile__ ("isync");
-
-				/* re-initialize memory, write the location again
-				 * NOT injecting errors this time */
-				*i = 0xcafecafecafecafeULL;
-				__asm__ __volatile__ ("sync");
-
-				/* enable errors for ECC */
-				ddr->err_disable &= ECC_ERROR_ENABLE;
-				__asm__ __volatile__ ("sync");
-				__asm__ __volatile__ ("isync");
-			}
-
-			icache_enable();
-			enable_interrupts();
-
-			return 0;
-		}
-	}
-
-	printf ("Usage:\n%s\n", cmdtp->usage);
-	return 1;
-}
-
-U_BOOT_CMD(
-	ecc,     4,     0,      do_ecc,
-	"ecc     - support for DDR ECC features\n",
-	"status              - print out status info\n"
-	"ecc captureclear        - clear capture regs data\n"
-	"ecc sbecnt <val>        - set Single-Bit Error counter\n"
-	"ecc sbethr <val>        - set Single-Bit Threshold\n"
-	"ecc errdisable <flag>   - clear/set disable Memory Error Disable, flag:\n"
-	"  [-|+]sbe - Single-Bit Error\n"
-	"  [-|+]mbe - Multiple-Bit Error\n"
-	"  [-|+]mse - Memory Select Error\n"
-	"  [-|+]all - all errors\n"
-	"ecc errdetectclr <flag> - clear Memory Error Detect, flag:\n"
-	"  mme - Multiple Memory Errors\n"
-	"  sbe - Single-Bit Error\n"
-	"  mbe - Multiple-Bit Error\n"
-	"  mse - Memory Select Error\n"
-	"  all - all errors\n"
-	"ecc injectdatahi <hi>  - set Memory Data Path Error Injection Mask High\n"
-	"ecc injectdatalo <lo>  - set Memory Data Path Error Injection Mask Low\n"
-	"ecc injectecc <ecc>    - set ECC Error Injection Mask\n"
-	"ecc inject <en|dis>    - enable/disable error injection\n"
-	"ecc mirror <en|dis>    - enable/disable mirror byte\n"
-	"ecc test <addr> <cnt>  - test mem region:\n"
-	"  - enables injects\n"
-	"  - writes pattern injecting errors\n"
-	"  - disables injects\n"
-	"  - reads pattern back, generates error\n"
-	"  - re-inits memory"
-);
-#endif /* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */
-
 #if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
 void
 ft_board_setup(void *blob, bd_t *bd)
diff --git a/board/mpc8349itx/config.mk b/board/mpc8349itx/config.mk
index 1901fdc2cef9891f3127f434d5128d53c32355cf..79f1765fa1b05873e901311510167a97e1d7c7bb 100644
--- a/board/mpc8349itx/config.mk
+++ b/board/mpc8349itx/config.mk
@@ -29,9 +29,3 @@ sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
 ifndef TEXT_BASE
 TEXT_BASE  =   0xFEF00000
 endif
-
-ifneq ($(OBJTREE),$(SRCTREE))
-# We are building u-boot in a separate directory, use generated
-# .lds script from OBJTREE directory.
-LDSCRIPT := $(OBJTREE)/board/$(BOARDDIR)/u-boot.lds
-endif
diff --git a/board/mpc8360emds/mpc8360emds.c b/board/mpc8360emds/mpc8360emds.c
index 562eb8b53af29deab02ed9f27a707e7f33c997a6..3fa093d1d55eb598503c1ff94b5369db70312443 100644
--- a/board/mpc8360emds/mpc8360emds.c
+++ b/board/mpc8360emds/mpc8360emds.c
@@ -1,8 +1,6 @@
 /*
  * Copyright (C) 2006 Freescale Semiconductor, Inc.
- *
  * Dave Liu <daveliu@freescale.com>
- * based on board/mpc8349emds/mpc8349emds.c
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -19,7 +17,6 @@
 #include <i2c.h>
 #include <spd.h>
 #include <miiphy.h>
-#include <command.h>
 #if defined(CONFIG_PCI)
 #include <pci.h>
 #endif
@@ -30,8 +27,7 @@
 #endif
 #if defined(CONFIG_OF_FLAT_TREE)
 #include <ft_build.h>
-#endif
-#if defined(CONFIG_OF_LIBFDT)
+#elif defined(CONFIG_OF_LIBFDT)
 #include <libfdt.h>
 #include <libfdt_env.h>
 #endif
@@ -103,7 +99,9 @@ int board_early_init_f(void)
 
 	/* Disable G1TXCLK, G2TXCLK h/w buffers (rev.2 h/w bug workaround) */
 	if (immr->sysconf.spridr == SPR_8360_REV20 ||
-	    immr->sysconf.spridr == SPR_8360E_REV20)
+	    immr->sysconf.spridr == SPR_8360E_REV20 ||
+	    immr->sysconf.spridr == SPR_8360_REV21 ||
+	    immr->sysconf.spridr == SPR_8360E_REV21)
 		bcsr[0xe] = 0x30;
 
 	return 0;
@@ -287,381 +285,6 @@ void sdram_init(void)
 }
 #endif
 
-#if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD)
-/*
- * ECC user commands
- */
-void ecc_print_status(void)
-{
-	volatile immap_t *immap = (immap_t *) CFG_IMMR;
-	volatile ddr83xx_t *ddr = &immap->ddr;
-
-	printf("\nECC mode: %s\n\n",
-	       (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF");
-
-	/* Interrupts */
-	printf("Memory Error Interrupt Enable:\n");
-	printf("  Multiple-Bit Error Interrupt Enable: %d\n",
-	       (ddr->err_int_en & ECC_ERR_INT_EN_MBEE) ? 1 : 0);
-	printf("  Single-Bit Error Interrupt Enable: %d\n",
-	       (ddr->err_int_en & ECC_ERR_INT_EN_SBEE) ? 1 : 0);
-	printf("  Memory Select Error Interrupt Enable: %d\n\n",
-	       (ddr->err_int_en & ECC_ERR_INT_EN_MSEE) ? 1 : 0);
-
-	/* Error disable */
-	printf("Memory Error Disable:\n");
-	printf("  Multiple-Bit Error Disable: %d\n",
-	       (ddr->err_disable & ECC_ERROR_DISABLE_MBED) ? 1 : 0);
-	printf("  Sinle-Bit Error Disable: %d\n",
-	       (ddr->err_disable & ECC_ERROR_DISABLE_SBED) ? 1 : 0);
-	printf("  Memory Select Error Disable: %d\n\n",
-	       (ddr->err_disable & ECC_ERROR_DISABLE_MSED) ? 1 : 0);
-
-	/* Error injection */
-	printf("Memory Data Path Error Injection Mask High/Low: %08lx %08lx\n",
-	       ddr->data_err_inject_hi, ddr->data_err_inject_lo);
-
-	printf("Memory Data Path Error Injection Mask ECC:\n");
-	printf("  ECC Mirror Byte: %d\n",
-	       (ddr->ecc_err_inject & ECC_ERR_INJECT_EMB) ? 1 : 0);
-	printf("  ECC Injection Enable: %d\n",
-	       (ddr->ecc_err_inject & ECC_ERR_INJECT_EIEN) ? 1 : 0);
-	printf("  ECC Error Injection Mask: 0x%02x\n\n",
-	       ddr->ecc_err_inject & ECC_ERR_INJECT_EEIM);
-
-	/* SBE counter/threshold */
-	printf("Memory Single-Bit Error Management (0..255):\n");
-	printf("  Single-Bit Error Threshold: %d\n",
-	       (ddr->err_sbe & ECC_ERROR_MAN_SBET) >> ECC_ERROR_MAN_SBET_SHIFT);
-	printf("  Single-Bit Error Counter: %d\n\n",
-	       (ddr->err_sbe & ECC_ERROR_MAN_SBEC) >> ECC_ERROR_MAN_SBEC_SHIFT);
-
-	/* Error detect */
-	printf("Memory Error Detect:\n");
-	printf("  Multiple Memory Errors: %d\n",
-	       (ddr->err_detect & ECC_ERROR_DETECT_MME) ? 1 : 0);
-	printf("  Multiple-Bit Error: %d\n",
-	       (ddr->err_detect & ECC_ERROR_DETECT_MBE) ? 1 : 0);
-	printf("  Single-Bit Error: %d\n",
-	       (ddr->err_detect & ECC_ERROR_DETECT_SBE) ? 1 : 0);
-	printf("  Memory Select Error: %d\n\n",
-	       (ddr->err_detect & ECC_ERROR_DETECT_MSE) ? 1 : 0);
-
-	/* Capture data */
-	printf("Memory Error Address Capture: 0x%08lx\n", ddr->capture_address);
-	printf("Memory Data Path Read Capture High/Low: %08lx %08lx\n",
-	       ddr->capture_data_hi, ddr->capture_data_lo);
-	printf("Memory Data Path Read Capture ECC: 0x%02x\n\n",
-	       ddr->capture_ecc & CAPTURE_ECC_ECE);
-
-	printf("Memory Error Attributes Capture:\n");
-	printf(" Data Beat Number: %d\n",
-	       (ddr->capture_attributes & ECC_CAPT_ATTR_BNUM) >>
-	       ECC_CAPT_ATTR_BNUM_SHIFT);
-	printf("  Transaction Size: %d\n",
-	       (ddr->capture_attributes & ECC_CAPT_ATTR_TSIZ) >>
-	       ECC_CAPT_ATTR_TSIZ_SHIFT);
-	printf("  Transaction Source: %d\n",
-	       (ddr->capture_attributes & ECC_CAPT_ATTR_TSRC) >>
-	       ECC_CAPT_ATTR_TSRC_SHIFT);
-	printf("  Transaction Type: %d\n",
-	       (ddr->capture_attributes & ECC_CAPT_ATTR_TTYP) >>
-	       ECC_CAPT_ATTR_TTYP_SHIFT);
-	printf("  Error Information Valid: %d\n\n",
-	       ddr->capture_attributes & ECC_CAPT_ATTR_VLD);
-}
-
-int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
-{
-	volatile immap_t *immap = (immap_t *) CFG_IMMR;
-	volatile ddr83xx_t *ddr = &immap->ddr;
-	volatile u32 val;
-	u64 *addr;
-	u32 count;
-	register u64 *i;
-	u32 ret[2];
-	u32 pattern[2];
-	u32 writeback[2];
-
-	/* The pattern is written into memory to generate error */
-	pattern[0] = 0xfedcba98UL;
-	pattern[1] = 0x76543210UL;
-
-	/* After injecting error, re-initialize the memory with the value */
-	writeback[0] = 0x01234567UL;
-	writeback[1] = 0x89abcdefUL;
-
-	if (argc > 4) {
-		printf("Usage:\n%s\n", cmdtp->usage);
-		return 1;
-	}
-
-	if (argc == 2) {
-		if (strcmp(argv[1], "status") == 0) {
-			ecc_print_status();
-			return 0;
-		} else if (strcmp(argv[1], "captureclear") == 0) {
-			ddr->capture_address = 0;
-			ddr->capture_data_hi = 0;
-			ddr->capture_data_lo = 0;
-			ddr->capture_ecc = 0;
-			ddr->capture_attributes = 0;
-			return 0;
-		}
-	}
-	if (argc == 3) {
-		if (strcmp(argv[1], "sbecnt") == 0) {
-			val = simple_strtoul(argv[2], NULL, 10);
-			if (val > 255) {
-				printf("Incorrect Counter value, "
-				       "should be 0..255\n");
-				return 1;
-			}
-
-			val = (val << ECC_ERROR_MAN_SBEC_SHIFT);
-			val |= (ddr->err_sbe & ECC_ERROR_MAN_SBET);
-
-			ddr->err_sbe = val;
-			return 0;
-		} else if (strcmp(argv[1], "sbethr") == 0) {
-			val = simple_strtoul(argv[2], NULL, 10);
-			if (val > 255) {
-				printf("Incorrect Counter value, "
-				       "should be 0..255\n");
-				return 1;
-			}
-
-			val = (val << ECC_ERROR_MAN_SBET_SHIFT);
-			val |= (ddr->err_sbe & ECC_ERROR_MAN_SBEC);
-
-			ddr->err_sbe = val;
-			return 0;
-		} else if (strcmp(argv[1], "errdisable") == 0) {
-			val = ddr->err_disable;
-
-			if (strcmp(argv[2], "+sbe") == 0) {
-				val |= ECC_ERROR_DISABLE_SBED;
-			} else if (strcmp(argv[2], "+mbe") == 0) {
-				val |= ECC_ERROR_DISABLE_MBED;
-			} else if (strcmp(argv[2], "+mse") == 0) {
-				val |= ECC_ERROR_DISABLE_MSED;
-			} else if (strcmp(argv[2], "+all") == 0) {
-				val |= (ECC_ERROR_DISABLE_SBED |
-					ECC_ERROR_DISABLE_MBED |
-					ECC_ERROR_DISABLE_MSED);
-			} else if (strcmp(argv[2], "-sbe") == 0) {
-				val &= ~ECC_ERROR_DISABLE_SBED;
-			} else if (strcmp(argv[2], "-mbe") == 0) {
-				val &= ~ECC_ERROR_DISABLE_MBED;
-			} else if (strcmp(argv[2], "-mse") == 0) {
-				val &= ~ECC_ERROR_DISABLE_MSED;
-			} else if (strcmp(argv[2], "-all") == 0) {
-				val &= ~(ECC_ERROR_DISABLE_SBED |
-					 ECC_ERROR_DISABLE_MBED |
-					 ECC_ERROR_DISABLE_MSED);
-			} else {
-				printf("Incorrect err_disable field\n");
-				return 1;
-			}
-
-			ddr->err_disable = val;
-			__asm__ __volatile__("sync");
-			__asm__ __volatile__("isync");
-			return 0;
-		} else if (strcmp(argv[1], "errdetectclr") == 0) {
-			val = ddr->err_detect;
-
-			if (strcmp(argv[2], "mme") == 0) {
-				val |= ECC_ERROR_DETECT_MME;
-			} else if (strcmp(argv[2], "sbe") == 0) {
-				val |= ECC_ERROR_DETECT_SBE;
-			} else if (strcmp(argv[2], "mbe") == 0) {
-				val |= ECC_ERROR_DETECT_MBE;
-			} else if (strcmp(argv[2], "mse") == 0) {
-				val |= ECC_ERROR_DETECT_MSE;
-			} else if (strcmp(argv[2], "all") == 0) {
-				val |= (ECC_ERROR_DETECT_MME |
-					ECC_ERROR_DETECT_MBE |
-					ECC_ERROR_DETECT_SBE |
-					ECC_ERROR_DETECT_MSE);
-			} else {
-				printf("Incorrect err_detect field\n");
-				return 1;
-			}
-
-			ddr->err_detect = val;
-			return 0;
-		} else if (strcmp(argv[1], "injectdatahi") == 0) {
-			val = simple_strtoul(argv[2], NULL, 16);
-
-			ddr->data_err_inject_hi = val;
-			return 0;
-		} else if (strcmp(argv[1], "injectdatalo") == 0) {
-			val = simple_strtoul(argv[2], NULL, 16);
-
-			ddr->data_err_inject_lo = val;
-			return 0;
-		} else if (strcmp(argv[1], "injectecc") == 0) {
-			val = simple_strtoul(argv[2], NULL, 16);
-			if (val > 0xff) {
-				printf("Incorrect ECC inject mask, "
-				       "should be 0x00..0xff\n");
-				return 1;
-			}
-			val |= (ddr->ecc_err_inject & ~ECC_ERR_INJECT_EEIM);
-
-			ddr->ecc_err_inject = val;
-			return 0;
-		} else if (strcmp(argv[1], "inject") == 0) {
-			val = ddr->ecc_err_inject;
-
-			if (strcmp(argv[2], "en") == 0)
-				val |= ECC_ERR_INJECT_EIEN;
-			else if (strcmp(argv[2], "dis") == 0)
-				val &= ~ECC_ERR_INJECT_EIEN;
-			else
-				printf("Incorrect command\n");
-
-			ddr->ecc_err_inject = val;
-			__asm__ __volatile__("sync");
-			__asm__ __volatile__("isync");
-			return 0;
-		} else if (strcmp(argv[1], "mirror") == 0) {
-			val = ddr->ecc_err_inject;
-
-			if (strcmp(argv[2], "en") == 0)
-				val |= ECC_ERR_INJECT_EMB;
-			else if (strcmp(argv[2], "dis") == 0)
-				val &= ~ECC_ERR_INJECT_EMB;
-			else
-				printf("Incorrect command\n");
-
-			ddr->ecc_err_inject = val;
-			return 0;
-		}
-	}
-	if (argc == 4) {
-		if (strcmp(argv[1], "testdw") == 0) {
-			addr = (u64 *) simple_strtoul(argv[2], NULL, 16);
-			count = simple_strtoul(argv[3], NULL, 16);
-
-			if ((u32) addr % 8) {
-				printf("Address not alligned on "
-				       "double word boundary\n");
-				return 1;
-			}
-			disable_interrupts();
-
-			for (i = addr; i < addr + count; i++) {
-
-				/* enable injects */
-				ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
-				__asm__ __volatile__("sync");
-				__asm__ __volatile__("isync");
-
-				/* write memory location injecting errors */
-				ppcDWstore((u32 *) i, pattern);
-				__asm__ __volatile__("sync");
-
-				/* disable injects */
-				ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
-				__asm__ __volatile__("sync");
-				__asm__ __volatile__("isync");
-
-				/* read data, this generates ECC error */
-				ppcDWload((u32 *) i, ret);
-				__asm__ __volatile__("sync");
-
-				/* re-initialize memory, double word write the location again,
-				 * generates new ECC code this time */
-				ppcDWstore((u32 *) i, writeback);
-				__asm__ __volatile__("sync");
-			}
-			enable_interrupts();
-			return 0;
-		}
-		if (strcmp(argv[1], "testword") == 0) {
-			addr = (u64 *) simple_strtoul(argv[2], NULL, 16);
-			count = simple_strtoul(argv[3], NULL, 16);
-
-			if ((u32) addr % 8) {
-				printf("Address not alligned on "
-				       "double word boundary\n");
-				return 1;
-			}
-			disable_interrupts();
-
-			for (i = addr; i < addr + count; i++) {
-
-				/* enable injects */
-				ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
-				__asm__ __volatile__("sync");
-				__asm__ __volatile__("isync");
-
-				/* write memory location injecting errors */
-				*(u32 *) i = 0xfedcba98UL;
-				__asm__ __volatile__("sync");
-
-				/* sub double word write,
-				 * bus will read-modify-write,
-				 * generates ECC error */
-				*((u32 *) i + 1) = 0x76543210UL;
-				__asm__ __volatile__("sync");
-
-				/* disable injects */
-				ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
-				__asm__ __volatile__("sync");
-				__asm__ __volatile__("isync");
-
-				/* re-initialize memory,
-				 * double word write the location again,
-				 * generates new ECC code this time */
-				ppcDWstore((u32 *) i, writeback);
-				__asm__ __volatile__("sync");
-			}
-			enable_interrupts();
-			return 0;
-		}
-	}
-	printf("Usage:\n%s\n", cmdtp->usage);
-	return 1;
-}
-
-U_BOOT_CMD(ecc, 4, 0, do_ecc,
-	   "ecc     - support for DDR ECC features\n",
-	   "status              - print out status info\n"
-	   "ecc captureclear        - clear capture regs data\n"
-	   "ecc sbecnt <val>        - set Single-Bit Error counter\n"
-	   "ecc sbethr <val>        - set Single-Bit Threshold\n"
-	   "ecc errdisable <flag>   - clear/set disable Memory Error Disable, flag:\n"
-	   "  [-|+]sbe - Single-Bit Error\n"
-	   "  [-|+]mbe - Multiple-Bit Error\n"
-	   "  [-|+]mse - Memory Select Error\n"
-	   "  [-|+]all - all errors\n"
-	   "ecc errdetectclr <flag> - clear Memory Error Detect, flag:\n"
-	   "  mme - Multiple Memory Errors\n"
-	   "  sbe - Single-Bit Error\n"
-	   "  mbe - Multiple-Bit Error\n"
-	   "  mse - Memory Select Error\n"
-	   "  all - all errors\n"
-	   "ecc injectdatahi <hi>  - set Memory Data Path Error Injection Mask High\n"
-	   "ecc injectdatalo <lo>  - set Memory Data Path Error Injection Mask Low\n"
-	   "ecc injectecc <ecc>    - set ECC Error Injection Mask\n"
-	   "ecc inject <en|dis>    - enable/disable error injection\n"
-	   "ecc mirror <en|dis>    - enable/disable mirror byte\n"
-	   "ecc testdw <addr> <cnt>  - test mem region with double word access:\n"
-	   "  - enables injects\n"
-	   "  - writes pattern injecting errors with double word access\n"
-	   "  - disables injects\n"
-	   "  - reads pattern back with double word access, generates error\n"
-	   "  - re-inits memory\n"
-	   "ecc testword <addr> <cnt>  - test mem region with word access:\n"
-	   "  - enables injects\n"
-	   "  - writes pattern injecting errors with word access\n"
-	   "  - writes pattern with word access, generates error\n"
-	   "  - disables injects\n" "  - re-inits memory");
-#endif				/* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */
-
 #if (defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)) \
      && defined(CONFIG_OF_BOARD_SETUP)
 
@@ -681,11 +304,11 @@ ft_board_setup(void *blob, bd_t *bd)
 	int nodeoffset;
 	int tmp[2];
 
-	nodeoffset = fdt_path_offset (fdt, "/memory");
+	nodeoffset = fdt_find_node_by_path(blob, "/memory");
 	if (nodeoffset >= 0) {
 		tmp[0] = cpu_to_be32(bd->bi_memstart);
 		tmp[1] = cpu_to_be32(bd->bi_memsize);
-		fdt_setprop(fdt, nodeoffset, "reg", tmp, sizeof(tmp));
+		fdt_setprop(blob, nodeoffset, "reg", tmp, sizeof(tmp));
 	}
 #else
 	u32 *p;
diff --git a/board/mpc8360emds/pci.c b/board/mpc8360emds/pci.c
index 158effe0a9f8befe116518a927c3ddabef439ca0..8f904710ca88d161ddd9d5e48f5502769bf49143 100644
--- a/board/mpc8360emds/pci.c
+++ b/board/mpc8360emds/pci.c
@@ -20,8 +20,7 @@
 #include <i2c.h>
 #if defined(CONFIG_OF_FLAT_TREE)
 #include <ft_build.h>
-#endif
-#if defined(CONFIG_OF_LIBFDT)
+#elif defined(CONFIG_OF_LIBFDT)
 #include <libfdt.h>
 #include <libfdt_env.h>
 #endif
@@ -207,7 +206,7 @@ void pci_init_board(void)
 
 	/* Switch temporarily to I2C bus #2 */
 	orig_i2c_bus = i2c_get_bus_num();
- 	i2c_set_bus_num(1);
+	i2c_set_bus_num(1);
 
 	val8 = 0;
 	i2c_write(0x23, 0x6, 1, &val8, 1);
@@ -311,26 +310,25 @@ ft_pci_setup(void *blob, bd_t *bd)
 	int err;
 	int tmp[2];
 
-	nodeoffset = fdt_path_offset (fdt, "/" OF_SOC "/pci@8500");
+	nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8500");
 	if (nodeoffset >= 0) {
 		tmp[0] = cpu_to_be32(hose[0].first_busno);
 		tmp[1] = cpu_to_be32(hose[0].last_busno);
-		err = fdt_setprop(fdt, nodeoffset, "bus-range", tmp, sizeof(tmp));
+		err = fdt_setprop(blob, nodeoffset, "bus-range", tmp, sizeof(tmp));
 	}
 }
-#endif				/* CONFIG_OF_LIBFDT */
-#ifdef CONFIG_OF_FLAT_TREE
+#elif defined(CONFIG_OF_FLAT_TREE)
 void
 ft_pci_setup(void *blob, bd_t *bd)
 {
-       	u32 *p;
-       	int len;
+	u32 *p;
+	int len;
 
-       	p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
-       	if (p != NULL) {
+	p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
+	if (p != NULL) {
 		p[0] = hose[0].first_busno;
 		p[1] = hose[0].last_busno;
-       	}
+	}
 }
 #endif				/* CONFIG_OF_FLAT_TREE */
 #endif				/* CONFIG_PCI */
diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c
index ef40c5474857a608ced29b27c4f7827ff7eccd46..92120b0d01ca8f0d3b779a19d059c4c922d18508 100644
--- a/board/trab/auto_update.c
+++ b/board/trab/auto_update.c
@@ -34,7 +34,7 @@
 
 #ifdef CONFIG_AUTO_UPDATE
 
-#ifndef CONFIG_USB_OHCI
+#ifndef CONFIG_USB_OHCI_NEW
 #error "must define CONFIG_USB_OHCI"
 #endif
 
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index de5a5148f69bda90b173a2910a60baeae62615c8..1db0fc3c03b14c4a3fb0761b2cc77bc4b562e7ed 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -193,7 +193,12 @@ int _do_setenv (int flag, int argc, char *argv[])
 		 * Ethernet Address and serial# can be set only once,
 		 * ver is readonly.
 		 */
+#ifdef CONFIG_HAS_UID
+		/* Allow serial# forced overwrite with 0xdeaf4add flag */
+		if ( ((strcmp (name, "serial#") == 0) && (flag != 0xdeaf4add)) ||
+#else
 		if ( (strcmp (name, "serial#") == 0) ||
+#endif
 		    ((strcmp (name, "ethaddr") == 0)
 #if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR)
 		     && (strcmp ((char *)env_get_addr(oldval),MK_STR(CONFIG_ETHADDR)) != 0)
@@ -397,7 +402,15 @@ void setenv (char *varname, char *varvalue)
 		_do_setenv (0, 3, argv);
 }
 
-int do_setenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+#ifdef CONFIG_HAS_UID
+void forceenv (char *varname, char *varvalue)
+{
+	char *argv[4] = { "forceenv", varname, varvalue, NULL };
+	_do_setenv (0xdeaf4add, 3, argv);
+}
+#endif
+
+int do_setenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	if (argc < 2) {
 		printf ("Usage:\n%s\n", cmdtp->usage);
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 56c21660fa006aa69d9912cb5f31ba99f0827379..aec558ad203b34a9a2a04a6091ab7b717aa4703f 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -129,7 +129,11 @@ static int usb_kbd_testc(void)
 static int usb_kbd_getc(void)
 {
 	char c;
-	while(usb_in_pointer==usb_out_pointer);
+	while(usb_in_pointer==usb_out_pointer) {
+#ifdef CFG_USB_EVENT_POLL
+		usb_event_poll();
+#endif
+	}
 	if((usb_out_pointer+1)==USB_KBD_BUFFER_LEN)
 		usb_out_pointer=0;
 	else
diff --git a/cpu/arm920t/at91rm9200/Makefile b/cpu/arm920t/at91rm9200/Makefile
index 8d4e478fb5e856dc693398e1af20a7e5fcb1a7f9..eaabad26a0cbeb2c59fa58ceb02db44b15a58898 100644
--- a/cpu/arm920t/at91rm9200/Makefile
+++ b/cpu/arm920t/at91rm9200/Makefile
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(SOC).a
 
 COBJS	= bcm5221.o dm9161.o ether.o i2c.o interrupts.o \
-	  lxt972.o serial.o usb_ohci.o
+	  lxt972.o serial.o usb.o
 SOBJS	= lowlevel_init.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/cpu/arm920t/at91rm9200/usb.c b/cpu/arm920t/at91rm9200/usb.c
new file mode 100644
index 0000000000000000000000000000000000000000..366262e4ccd0c2f5b71f235a4d2fdd50a82f7183
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/usb.c
@@ -0,0 +1,53 @@
+/*
+ * (C) Copyright 2006
+ * DENX Software Engineering <mk@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <common.h>
+
+#if defined(CONFIG_USB_OHCI_NEW) && defined(CFG_USB_OHCI_CPU_INIT)
+# ifdef CONFIG_AT91RM9200
+
+#include <asm/arch/hardware.h>
+
+int usb_cpu_init()
+{
+	/* Enable USB host clock. */
+	*AT91C_PMC_SCER = AT91C_PMC_UHP;	/* 48MHz clock enabled for UHP */
+	*AT91C_PMC_PCER = 1 << AT91C_ID_UHP;	/* Peripheral Clock Enable Register */
+	return 0;
+}
+
+int usb_cpu_stop()
+{
+	/* Initialization failed */
+	*AT91C_PMC_PCDR = 1 << AT91C_ID_UHP;	/* Peripheral Clock Disable Register */
+	*AT91C_PMC_SCDR = AT91C_PMC_UHP;	/* 48MHz clock disabled for UHP */
+	return 0;
+}
+
+int usb_cpu_init_fail()
+{
+	usb_cpu_stop();
+}
+
+# endif /* CONFIG_AT91RM9200 */
+#endif /* defined(CONFIG_USB_OHCI) && defined(CFG_USB_OHCI_CPU_INIT) */
diff --git a/cpu/arm920t/s3c24x0/Makefile b/cpu/arm920t/s3c24x0/Makefile
index 3a7c4b35fd8a0fa095bd8903cf03a17912a2b417..0ff36c596a36d0baf603d0b7172177631ac7a6df 100644
--- a/cpu/arm920t/s3c24x0/Makefile
+++ b/cpu/arm920t/s3c24x0/Makefile
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(SOC).a
 
 COBJS	= i2c.o interrupts.o serial.o speed.o \
-	  usb_ohci.o
+	  usb.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/arm920t/s3c24x0/usb.c b/cpu/arm920t/s3c24x0/usb.c
new file mode 100644
index 0000000000000000000000000000000000000000..ef5d5bf71b139e50e8b80d1989b5eb725f3f5ece
--- /dev/null
+++ b/cpu/arm920t/s3c24x0/usb.c
@@ -0,0 +1,72 @@
+/*
+ * (C) Copyright 2006
+ * DENX Software Engineering <mk@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <common.h>
+
+#if defined(CONFIG_USB_OHCI_NEW) && defined(CFG_USB_OHCI_CPU_INIT)
+# if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
+
+#if defined(CONFIG_S3C2400)
+# include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+# include <s3c2410.h>
+#endif
+
+int usb_cpu_init (void)
+{
+
+	S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+	S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+
+	/*
+	 * Set the 48 MHz UPLL clocking. Values are taken from
+	 * "PLL value selection guide", 6-23, s3c2400_UM.pdf.
+	 */
+	clk_power->UPLLCON = ((40 << 12) + (1 << 4) + 2);
+	gpio->MISCCR |= 0x8; /* 1 = use pads related USB for USB host */
+
+	/*
+	 * Enable USB host clock.
+	 */
+	clk_power->CLKCON |= (1 << 4);
+
+	return 0;
+}
+
+int usb_cpu_stop (void)
+{
+	S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+	/* may not want to do this */
+	clk_power->CLKCON &= ~(1 << 4);
+	return 0;
+}
+
+int usb_cpu_init_fail (void)
+{
+	S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+	clk_power->CLKCON &= ~(1 << 4);
+	return 0;
+}
+
+# endif /* defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) */
+#endif /* defined(CONFIG_USB_OHCI) && defined(CFG_USB_OHCI_CPU_INIT) */
diff --git a/cpu/arm926ejs/davinci/Makefile b/cpu/arm926ejs/davinci/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..0f77f402ed83bd7aa51edf695c619423c77fd503
--- /dev/null
+++ b/cpu/arm926ejs/davinci/Makefile
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).a
+
+COBJS	= timer.o ether.o lxt972.o dp83848.o i2c.o nand.o
+SOBJS	= lowlevel_init.o reset.o
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm926ejs/davinci/dp83848.c b/cpu/arm926ejs/davinci/dp83848.c
new file mode 100644
index 0000000000000000000000000000000000000000..5719845b3404fd034f3a6a4847f312423bc9fe9a
--- /dev/null
+++ b/cpu/arm926ejs/davinci/dp83848.c
@@ -0,0 +1,156 @@
+/*
+ * National Semiconductor DP83848 PHY Driver for TI DaVinci
+ * (TMS320DM644x) based boards.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * --------------------------------------------------------
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <common.h>
+#include <net.h>
+#include <dp83848.h>
+#include <asm/arch/emac_defs.h>
+
+#ifdef CONFIG_DRIVER_TI_EMAC
+
+#ifdef CONFIG_CMD_NET
+
+int dp83848_is_phy_connected(int phy_addr)
+{
+	u_int16_t	id1, id2;
+
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1))
+		return(0);
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2))
+		return(0);
+
+	if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI))
+		return(1);
+
+	return(0);
+}
+
+int dp83848_get_link_speed(int phy_addr)
+{
+	u_int16_t		tmp;
+	volatile emac_regs*	emac = (emac_regs *)EMAC_BASE_ADDR;
+
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
+		return(0);
+
+	if (!(tmp & DP83848_LINK_STATUS))	/* link up? */
+		return(0);
+
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp))
+		return(0);
+
+	/* Speed doesn't matter, there is no setting for it in EMAC... */
+	if (tmp & DP83848_SPEED) {
+		if (tmp & DP83848_DUPLEX) {
+			/* set DM644x EMAC for Full Duplex  */
+			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
+		} else {
+			/*set DM644x EMAC for Half Duplex  */
+			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
+		}
+
+		return(1);
+	} else {
+		if (tmp & DP83848_DUPLEX) {
+			/* set DM644x EMAC for Full Duplex  */
+			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
+		} else {
+			/*set DM644x EMAC for Half Duplex  */
+			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
+		}
+
+		return(1);
+	}
+
+	return(0);
+}
+
+
+int dp83848_init_phy(int phy_addr)
+{
+	int	ret = 1;
+
+	if (!dp83848_get_link_speed(phy_addr)) {
+		/* Try another time */
+		udelay(100000);
+		ret = dp83848_get_link_speed(phy_addr);
+	}
+
+	/* Disable PHY Interrupts */
+	dm644x_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0);
+
+	return(ret);
+}
+
+
+int dp83848_auto_negotiate(int phy_addr)
+{
+	u_int16_t	tmp;
+
+
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
+		return(0);
+
+	/* Restart Auto_negotiation  */
+	tmp &= ~DP83848_AUTONEG;	/* remove autonegotiation enable */
+	tmp |= DP83848_ISOLATE;		/* Electrically isolate PHY */
+	dm644x_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
+
+	/* Set the Auto_negotiation Advertisement Register
+	 * MII advertising for Next page, 100BaseTxFD and HD,
+	 * 10BaseTFD and HD, IEEE 802.3
+	 */
+	tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX |
+	 	DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3;
+	dm644x_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp);
+
+
+	/* Read Control Register */
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
+		return(0);
+
+	tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE;
+	dm644x_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
+
+	/* Restart Auto_negotiation  */
+	tmp |= DP83848_RESTART_AUTONEG;
+	dm644x_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
+
+	/*check AutoNegotiate complete */
+	udelay(10000);
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
+		return(0);
+
+	if (!(tmp & DP83848_AUTONEG_COMP))
+		return(0);
+
+	return (dp83848_get_link_speed(phy_addr));
+}
+
+#endif	/* CONFIG_CMD_NET */
+
+#endif	/* CONFIG_DRIVER_ETHER */
diff --git a/cpu/arm926ejs/davinci/ether.c b/cpu/arm926ejs/davinci/ether.c
new file mode 100644
index 0000000000000000000000000000000000000000..32e81d11d4e0ed11d82d9c1fbc8b5480ff8fa8e9
--- /dev/null
+++ b/cpu/arm926ejs/davinci/ether.c
@@ -0,0 +1,650 @@
+/*
+ * Ethernet driver for TI TMS320DM644x (DaVinci) chips.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Parts shamelessly stolen from TI's dm644x_emac.c. Original copyright
+ * follows:
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * dm644x_emac.c
+ *
+ * TI DaVinci (DM644X) EMAC peripheral driver source for DV-EVM
+ *
+ * Copyright (C) 2005 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+
+ * Modifications:
+ * ver. 1.0: Sep 2005, Anant Gole - Created EMAC version for uBoot.
+ * ver  1.1: Nov 2005, Anant Gole - Extended the RX logic for multiple descriptors
+ *
+ */
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <miiphy.h>
+#include <asm/arch/emac_defs.h>
+
+#ifdef CONFIG_DRIVER_TI_EMAC
+
+#ifdef CONFIG_CMD_NET
+
+unsigned int	emac_dbg = 0;
+#define debug_emac(fmt,args...)	if (emac_dbg) printf(fmt,##args)
+
+/* Internal static functions */
+static int dm644x_eth_hw_init (void);
+static int dm644x_eth_open (void);
+static int dm644x_eth_close (void);
+static int dm644x_eth_send_packet (volatile void *packet, int length);
+static int dm644x_eth_rcv_packet (void);
+static void dm644x_eth_mdio_enable(void);
+
+static int gen_init_phy(int phy_addr);
+static int gen_is_phy_connected(int phy_addr);
+static int gen_get_link_speed(int phy_addr);
+static int gen_auto_negotiate(int phy_addr);
+
+/* Wrappers exported to the U-Boot proper */
+int eth_hw_init(void)
+{
+	return(dm644x_eth_hw_init());
+}
+
+int eth_init(bd_t * bd)
+{
+	return(dm644x_eth_open());
+}
+
+void eth_halt(void)
+{
+	dm644x_eth_close();
+}
+
+int eth_send(volatile void *packet, int length)
+{
+	return(dm644x_eth_send_packet(packet, length));
+}
+
+int eth_rx(void)
+{
+	return(dm644x_eth_rcv_packet());
+}
+
+void eth_mdio_enable(void)
+{
+	dm644x_eth_mdio_enable();
+}
+/* End of wrappers */
+
+
+static u_int8_t dm644x_eth_mac_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+/*
+ * This function must be called before emac_open() if you want to override
+ * the default mac address.
+ */
+void dm644x_eth_set_mac_addr(const u_int8_t *addr)
+{
+	int i;
+
+	for (i = 0; i < sizeof (dm644x_eth_mac_addr); i++) {
+		dm644x_eth_mac_addr[i] = addr[i];
+	}
+}
+
+/* EMAC Addresses */
+static volatile emac_regs	*adap_emac = (emac_regs *)EMAC_BASE_ADDR;
+static volatile ewrap_regs	*adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR;
+static volatile mdio_regs	*adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR;
+
+/* EMAC descriptors */
+static volatile emac_desc	*emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE);
+static volatile emac_desc	*emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE);
+static volatile emac_desc	*emac_rx_active_head = 0;
+static volatile emac_desc	*emac_rx_active_tail = 0;
+static int			emac_rx_queue_active = 0;
+
+/* Receive packet buffers */
+static unsigned char		emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
+
+/* PHY address for a discovered PHY (0xff - not found) */
+static volatile u_int8_t	active_phy_addr = 0xff;
+
+phy_t				phy;
+
+static void dm644x_eth_mdio_enable(void)
+{
+	u_int32_t	clkdiv;
+
+	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+
+	adap_mdio->CONTROL = (clkdiv & 0xff) |
+		MDIO_CONTROL_ENABLE |
+		MDIO_CONTROL_FAULT |
+		MDIO_CONTROL_FAULT_ENABLE;
+
+	while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;}
+}
+
+/*
+ * Tries to find an active connected PHY. Returns 1 if address if found.
+ * If no active PHY (or more than one PHY) found returns 0.
+ * Sets active_phy_addr variable.
+ */
+static int dm644x_eth_phy_detect(void)
+{
+	u_int32_t	phy_act_state;
+	int		i;
+
+	active_phy_addr = 0xff;
+
+	if ((phy_act_state = adap_mdio->ALIVE) == 0)
+		return(0);				/* No active PHYs */
+
+	debug_emac("dm644x_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state);
+
+	for (i = 0; i < 32; i++) {
+		if (phy_act_state & (1 << i)) {
+			if (phy_act_state & ~(1 << i))
+				return(0);		/* More than one PHY */
+			else {
+				active_phy_addr = i;
+				return(1);
+			}
+		}
+	}
+
+	return(0);	/* Just to make GCC happy */
+}
+
+
+/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
+int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
+{
+	int	tmp;
+
+	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
+
+	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
+				MDIO_USERACCESS0_WRITE_READ |
+				((reg_num & 0x1f) << 21) |
+				((phy_addr & 0x1f) << 16);
+
+	/* Wait for command to complete */
+	while ((tmp = adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) {;}
+
+	if (tmp & MDIO_USERACCESS0_ACK) {
+		*data = tmp & 0xffff;
+		return(1);
+	}
+
+	*data = -1;
+	return(0);
+}
+
+/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */
+int dm644x_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
+{
+
+	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
+
+	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
+				MDIO_USERACCESS0_WRITE_WRITE |
+				((reg_num & 0x1f) << 21) |
+				((phy_addr & 0x1f) << 16) |
+				(data & 0xffff);
+
+	/* Wait for command to complete */
+	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
+
+	return(1);
+}
+
+/* PHY functions for a generic PHY */
+static int gen_init_phy(int phy_addr)
+{
+	int	ret = 1;
+
+	if (gen_get_link_speed(phy_addr)) {
+		/* Try another time */
+		ret = gen_get_link_speed(phy_addr);
+	}
+
+	return(ret);
+}
+
+static int gen_is_phy_connected(int phy_addr)
+{
+	u_int16_t	dummy;
+
+	return(dm644x_eth_phy_read(phy_addr, PHY_PHYIDR1, &dummy));
+}
+
+static int gen_get_link_speed(int phy_addr)
+{
+	u_int16_t	tmp;
+
+	if (dm644x_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) && (tmp & 0x04))
+		return(1);
+
+	return(0);
+}
+
+static int gen_auto_negotiate(int phy_addr)
+{
+	u_int16_t	tmp;
+
+	if (!dm644x_eth_phy_read(phy_addr, PHY_BMCR, &tmp))
+		return(0);
+
+	/* Restart Auto_negotiation  */
+	tmp |= PHY_BMCR_AUTON;
+	dm644x_eth_phy_write(phy_addr, PHY_BMCR, tmp);
+
+	/*check AutoNegotiate complete */
+	udelay (10000);
+	if (!dm644x_eth_phy_read(phy_addr, PHY_BMSR, &tmp))
+		return(0);
+
+	if (!(tmp & PHY_BMSR_AUTN_COMP))
+		return(0);
+
+	return(gen_get_link_speed(phy_addr));
+}
+/* End of generic PHY functions */
+
+
+#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
+static int dm644x_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value)
+{
+	return(dm644x_eth_phy_read(addr, reg, value) ? 0 : 1);
+}
+
+static int dm644x_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value)
+{
+	return(dm644x_eth_phy_write(addr, reg, value) ? 0 : 1);
+}
+
+int dm644x_eth_miiphy_initialize(bd_t *bis)
+{
+	miiphy_register(phy.name, dm644x_mii_phy_read, dm644x_mii_phy_write);
+
+	return(1);
+}
+#endif
+
+/*
+ * This function initializes the emac hardware. It does NOT initialize
+ * EMAC modules power or pin multiplexors, that is done by board_init()
+ * much earlier in bootup process. Returns 1 on success, 0 otherwise.
+ */
+static int dm644x_eth_hw_init(void)
+{
+	u_int32_t	phy_id;
+	u_int16_t	tmp;
+	int		i;
+
+	dm644x_eth_mdio_enable();
+
+	for (i = 0; i < 256; i++) {
+		if (adap_mdio->ALIVE)
+			break;
+		udelay(10);
+	}
+
+	if (i >= 256) {
+		printf("No ETH PHY detected!!!\n");
+		return(0);
+	}
+
+	/* Find if a PHY is connected and get it's address */
+	if (!dm644x_eth_phy_detect())
+		return(0);
+
+	/* Get PHY ID and initialize phy_ops for a detected PHY */
+	if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR1, &tmp)) {
+		active_phy_addr = 0xff;
+		return(0);
+	}
+
+	phy_id = (tmp << 16) & 0xffff0000;
+
+	if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR2, &tmp)) {
+		active_phy_addr = 0xff;
+		return(0);
+	}
+
+	phy_id |= tmp & 0x0000ffff;
+
+	switch (phy_id) {
+		case PHY_LXT972:
+			sprintf(phy.name, "LXT972 @ 0x%02x", active_phy_addr);
+			phy.init = lxt972_init_phy;
+			phy.is_phy_connected = lxt972_is_phy_connected;
+			phy.get_link_speed = lxt972_get_link_speed;
+			phy.auto_negotiate = lxt972_auto_negotiate;
+			break;
+		case PHY_DP83848:
+			sprintf(phy.name, "DP83848 @ 0x%02x", active_phy_addr);
+			phy.init = dp83848_init_phy;
+			phy.is_phy_connected = dp83848_is_phy_connected;
+			phy.get_link_speed = dp83848_get_link_speed;
+			phy.auto_negotiate = dp83848_auto_negotiate;
+			break;
+		default:
+			sprintf(phy.name, "GENERIC @ 0x%02x", active_phy_addr);
+			phy.init = gen_init_phy;
+			phy.is_phy_connected = gen_is_phy_connected;
+			phy.get_link_speed = gen_get_link_speed;
+			phy.auto_negotiate = gen_auto_negotiate;
+	}
+
+	return(1);
+}
+
+
+/* Eth device open */
+static int dm644x_eth_open(void)
+{
+	dv_reg_p		addr;
+	u_int32_t		clkdiv, cnt;
+	volatile emac_desc	*rx_desc;
+
+	debug_emac("+ emac_open\n");
+
+	/* Reset EMAC module and disable interrupts in wrapper */
+	adap_emac->SOFTRESET = 1;
+	while (adap_emac->SOFTRESET != 0) {;}
+	adap_ewrap->EWCTL = 0;
+	for (cnt = 0; cnt < 5; cnt++) {
+		clkdiv = adap_ewrap->EWCTL;
+	}
+
+	rx_desc = emac_rx_desc;
+
+	adap_emac->TXCONTROL = 0x01;
+	adap_emac->RXCONTROL = 0x01;
+
+	/* Set MAC Addresses & Init multicast Hash to 0 (disable any multicast receive) */
+	/* Using channel 0 only - other channels are disabled */
+	adap_emac->MACINDEX = 0;
+	adap_emac->MACADDRHI =
+		(dm644x_eth_mac_addr[3] << 24) |
+		(dm644x_eth_mac_addr[2] << 16) |
+		(dm644x_eth_mac_addr[1] << 8)  |
+		(dm644x_eth_mac_addr[0]);
+	adap_emac->MACADDRLO =
+		(dm644x_eth_mac_addr[5] << 8) |
+		(dm644x_eth_mac_addr[4]);
+
+	adap_emac->MACHASH1 = 0;
+	adap_emac->MACHASH2 = 0;
+
+	/* Set source MAC address - REQUIRED */
+	adap_emac->MACSRCADDRHI =
+		(dm644x_eth_mac_addr[3] << 24) |
+		(dm644x_eth_mac_addr[2] << 16) |
+		(dm644x_eth_mac_addr[1] << 8)  |
+		(dm644x_eth_mac_addr[0]);
+	adap_emac->MACSRCADDRLO =
+		(dm644x_eth_mac_addr[4] << 8) |
+		(dm644x_eth_mac_addr[5]);
+
+	/* Set DMA 8 TX / 8 RX Head pointers to 0 */
+	addr = &adap_emac->TX0HDP;
+	for(cnt = 0; cnt < 16; cnt++)
+		*addr++ = 0;
+
+	addr = &adap_emac->RX0HDP;
+	for(cnt = 0; cnt < 16; cnt++)
+		*addr++ = 0;
+
+	/* Clear Statistics (do this before setting MacControl register) */
+	addr = &adap_emac->RXGOODFRAMES;
+	for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
+		*addr++ = 0;
+
+	/* No multicast addressing */
+	adap_emac->MACHASH1 = 0;
+	adap_emac->MACHASH2 = 0;
+
+	/* Create RX queue and set receive process in place */
+	emac_rx_active_head = emac_rx_desc;
+	for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
+		rx_desc->next = (u_int32_t)(rx_desc + 1);
+		rx_desc->buffer = &emac_rx_buffers[cnt * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
+		rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
+		rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
+		rx_desc++;
+	}
+
+	/* Set the last descriptor's "next" parameter to 0 to end the RX desc list */
+	rx_desc--;
+	rx_desc->next = 0;
+	emac_rx_active_tail = rx_desc;
+	emac_rx_queue_active = 1;
+
+	/* Enable TX/RX */
+	adap_emac->RXMAXLEN = EMAC_MAX_ETHERNET_PKT_SIZE;
+	adap_emac->RXBUFFEROFFSET = 0;
+
+	/* No fancy configs - Use this for promiscous for debug - EMAC_RXMBPENABLE_RXCAFEN_ENABLE */
+	adap_emac->RXMBPENABLE = EMAC_RXMBPENABLE_RXBROADEN;
+
+	/* Enable ch 0 only */
+	adap_emac->RXUNICASTSET = 0x01;
+
+	/* Enable MII interface and Full duplex mode */
+	adap_emac->MACCONTROL = (EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE);
+
+	/* Init MDIO & get link state */
+	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+	adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);
+
+	if (!phy.get_link_speed(active_phy_addr))
+		return(0);
+
+	/* Start receive process */
+	adap_emac->RX0HDP = (u_int32_t)emac_rx_desc;
+
+	debug_emac("- emac_open\n");
+
+	return(1);
+}
+
+/* EMAC Channel Teardown */
+static void dm644x_eth_ch_teardown(int ch)
+{
+	dv_reg		dly = 0xff;
+	dv_reg		cnt;
+
+	debug_emac("+ emac_ch_teardown\n");
+
+	if (ch == EMAC_CH_TX) {
+		/* Init TX channel teardown */
+		adap_emac->TXTEARDOWN = 1;
+		for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->TX0CP) {
+			/* Wait here for Tx teardown completion interrupt to occur
+			 * Note: A task delay can be called here to pend rather than
+			 * occupying CPU cycles - anyway it has been found that teardown
+			 * takes very few cpu cycles and does not affect functionality */
+			 dly--;
+			 udelay(1);
+			 if (dly == 0)
+			 	break;
+		}
+		adap_emac->TX0CP = cnt;
+		adap_emac->TX0HDP = 0;
+	} else {
+		/* Init RX channel teardown */
+		adap_emac->RXTEARDOWN = 1;
+		for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->RX0CP) {
+			/* Wait here for Rx teardown completion interrupt to occur
+			 * Note: A task delay can be called here to pend rather than
+			 * occupying CPU cycles - anyway it has been found that teardown
+			 * takes very few cpu cycles and does not affect functionality */
+			 dly--;
+			 udelay(1);
+			 if (dly == 0)
+			 	break;
+		}
+		adap_emac->RX0CP = cnt;
+		adap_emac->RX0HDP = 0;
+	}
+
+	debug_emac("- emac_ch_teardown\n");
+}
+
+/* Eth device close */
+static int dm644x_eth_close(void)
+{
+	debug_emac("+ emac_close\n");
+
+	dm644x_eth_ch_teardown(EMAC_CH_TX);	/* TX Channel teardown */
+	dm644x_eth_ch_teardown(EMAC_CH_RX);	/* RX Channel teardown */
+
+	/* Reset EMAC module and disable interrupts in wrapper */
+	adap_emac->SOFTRESET = 1;
+	adap_ewrap->EWCTL = 0;
+
+	debug_emac("- emac_close\n");
+	return(1);
+}
+
+static int tx_send_loop = 0;
+
+/*
+ * This function sends a single packet on the network and returns
+ * positive number (number of bytes transmitted) or negative for error
+ */
+static int dm644x_eth_send_packet(volatile void *packet, int length)
+{
+	int ret_status = -1;
+	tx_send_loop = 0;
+
+	/* Return error if no link */
+	if (!phy.get_link_speed(active_phy_addr))
+	{
+		printf("WARN: emac_send_packet: No link\n");
+		return (ret_status);
+	}
+
+	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
+	if (length < EMAC_MIN_ETHERNET_PKT_SIZE)
+	{
+		length = EMAC_MIN_ETHERNET_PKT_SIZE;
+	}
+
+	/* Populate the TX descriptor */
+	emac_tx_desc->next         = 0;
+	emac_tx_desc->buffer       = (u_int8_t *)packet;
+	emac_tx_desc->buff_off_len = (length & 0xffff);
+	emac_tx_desc->pkt_flag_len = ((length & 0xffff) |
+			EMAC_CPPI_SOP_BIT |
+			EMAC_CPPI_OWNERSHIP_BIT |
+			EMAC_CPPI_EOP_BIT);
+	/* Send the packet */
+	adap_emac->TX0HDP = (unsigned int)emac_tx_desc;
+
+	/* Wait for packet to complete or link down */
+	while (1) {
+	        if (!phy.get_link_speed(active_phy_addr)) {
+	        	dm644x_eth_ch_teardown(EMAC_CH_TX);
+	        	return (ret_status);
+	        }
+	        if (adap_emac->TXINTSTATRAW & 0x01) {
+	        	ret_status = length;
+	        	break;
+		}
+	        tx_send_loop++;
+	}
+
+	return(ret_status);
+}
+
+/*
+ * This function handles receipt of a packet from the network
+ */
+static int dm644x_eth_rcv_packet(void)
+{
+	volatile emac_desc	*rx_curr_desc;
+	volatile emac_desc	*curr_desc;
+	volatile emac_desc	*tail_desc;
+	int			status, ret = -1;
+
+	rx_curr_desc = emac_rx_active_head;
+	status = rx_curr_desc->pkt_flag_len;
+	if ((rx_curr_desc) && ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0)) {
+	        if (status & EMAC_CPPI_RX_ERROR_FRAME) {
+	        	/* Error in packet - discard it and requeue desc */
+	        	printf("WARN: emac_rcv_pkt: Error in packet\n");
+		} else {
+			NetReceive(rx_curr_desc->buffer, (rx_curr_desc->buff_off_len & 0xffff));
+			ret = rx_curr_desc->buff_off_len & 0xffff;
+	        }
+
+	        /* Ack received packet descriptor */
+	        adap_emac->RX0CP = (unsigned int)rx_curr_desc;
+	        curr_desc = rx_curr_desc;
+	        emac_rx_active_head = (volatile emac_desc *)rx_curr_desc->next;
+
+	        if (status & EMAC_CPPI_EOQ_BIT) {
+	        	if (emac_rx_active_head) {
+	        		adap_emac->RX0HDP = (unsigned int)emac_rx_active_head;
+			} else {
+				emac_rx_queue_active = 0;
+				printf("INFO:emac_rcv_packet: RX Queue not active\n");
+			}
+		}
+
+		/* Recycle RX descriptor */
+		rx_curr_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
+		rx_curr_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
+		rx_curr_desc->next = 0;
+
+		if (emac_rx_active_head == 0) {
+			printf("INFO: emac_rcv_pkt: active queue head = 0\n");
+			emac_rx_active_head = curr_desc;
+			emac_rx_active_tail = curr_desc;
+			if (emac_rx_queue_active != 0) {
+				adap_emac->RX0HDP = (unsigned int)emac_rx_active_head;
+				printf("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
+				emac_rx_queue_active = 1;
+			}
+		} else {
+			tail_desc = emac_rx_active_tail;
+			emac_rx_active_tail = curr_desc;
+			tail_desc->next = (unsigned int)curr_desc;
+			status = tail_desc->pkt_flag_len;
+			if (status & EMAC_CPPI_EOQ_BIT) {
+				adap_emac->RX0HDP = (unsigned int)curr_desc;
+				status &= ~EMAC_CPPI_EOQ_BIT;
+				tail_desc->pkt_flag_len = status;
+			}
+		}
+		return(ret);
+	}
+	return(0);
+}
+
+#endif /* CONFIG_CMD_NET */
+
+#endif /* CONFIG_DRIVER_TI_EMAC */
diff --git a/cpu/arm926ejs/davinci/i2c.c b/cpu/arm926ejs/davinci/i2c.c
new file mode 100644
index 0000000000000000000000000000000000000000..af9dc034c2ab1597aa0f6f26067ac150178551b6
--- /dev/null
+++ b/cpu/arm926ejs/davinci/i2c.c
@@ -0,0 +1,351 @@
+/*
+ * TI DaVinci (TMS320DM644x) I2C driver.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * --------------------------------------------------------
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <common.h>
+
+#ifdef CONFIG_DRIVER_DAVINCI_I2C
+
+#include <i2c.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/i2c_defs.h>
+
+#define CHECK_NACK() \
+	do {\
+		if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
+			REG(I2C_CON) = 0;\
+			return(1);\
+		}\
+	} while (0)
+
+
+static int wait_for_bus(void)
+{
+	int	stat, timeout;
+
+	REG(I2C_STAT) = 0xffff;
+
+	for (timeout = 0; timeout < 10; timeout++) {
+		if (!((stat = REG(I2C_STAT)) & I2C_STAT_BB)) {
+			REG(I2C_STAT) = 0xffff;
+			return(0);
+		}
+
+		REG(I2C_STAT) = stat;
+		udelay(50000);
+	}
+
+	REG(I2C_STAT) = 0xffff;
+	return(1);
+}
+
+
+static int poll_i2c_irq(int mask)
+{
+	int	stat, timeout;
+
+	for (timeout = 0; timeout < 10; timeout++) {
+		udelay(1000);
+		stat = REG(I2C_STAT);
+		if (stat & mask) {
+			return(stat);
+		}
+	}
+
+	REG(I2C_STAT) = 0xffff;
+	return(stat | I2C_TIMEOUT);
+}
+
+
+void flush_rx(void)
+{
+	int	dummy;
+
+	while (1) {
+		if (!(REG(I2C_STAT) & I2C_STAT_RRDY))
+			break;
+
+		dummy = REG(I2C_DRR);
+		REG(I2C_STAT) = I2C_STAT_RRDY;
+		udelay(1000);
+	}
+}
+
+
+void i2c_init(int speed, int slaveadd)
+{
+	u_int32_t	div, psc;
+
+	if (REG(I2C_CON) & I2C_CON_EN) {
+		REG(I2C_CON) = 0;
+		udelay (50000);
+	}
+
+	psc = 2;
+	div = (CFG_HZ_CLOCK / ((psc + 1) * speed)) - 10;	/* SCLL + SCLH */
+	REG(I2C_PSC) = psc;			/* 27MHz / (2 + 1) = 9MHz */
+	REG(I2C_SCLL) = (div * 50) / 100;	/* 50% Duty */
+	REG(I2C_SCLH) = div - REG(I2C_SCLL);
+
+	REG(I2C_OA) = slaveadd;
+	REG(I2C_CNT) = 0;
+
+	/* Interrupts must be enabled or I2C module won't work */
+	REG(I2C_IE) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
+		I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
+
+	/* Now enable I2C controller (get it out of reset) */
+	REG(I2C_CON) = I2C_CON_EN;
+
+	udelay(1000);
+}
+
+
+int i2c_probe(u_int8_t chip)
+{
+	int	rc = 1;
+
+	if (chip == REG(I2C_OA)) {
+		return(rc);
+	}
+
+	REG(I2C_CON) = 0;
+	if (wait_for_bus()) {return(1);}
+
+	/* try to read one byte from current (or only) address */
+	REG(I2C_CNT) = 1;
+	REG(I2C_SA) = chip;
+	REG(I2C_CON) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP);
+	udelay (50000);
+
+	if (!(REG(I2C_STAT) & I2C_STAT_NACK)) {
+		rc = 0;
+		flush_rx();
+		REG(I2C_STAT) = 0xffff;
+	} else {
+		REG(I2C_STAT) = 0xffff;
+		REG(I2C_CON) |= I2C_CON_STP;
+		udelay(20000);
+		if (wait_for_bus()) {return(1);}
+	}
+
+	flush_rx();
+	REG(I2C_STAT) = 0xffff;
+	REG(I2C_CNT) = 0;
+	return(rc);
+}
+
+
+int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+{
+	u_int32_t	tmp;
+	int		i;
+
+	if ((alen < 0) || (alen > 2)) {
+		printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
+		return(1);
+	}
+
+	if (wait_for_bus()) {return(1);}
+
+	if (alen != 0) {
+		/* Start address phase */
+		tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX;
+		REG(I2C_CNT) = alen;
+		REG(I2C_SA) = chip;
+		REG(I2C_CON) = tmp;
+
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+		CHECK_NACK();
+
+		switch (alen) {
+			case 2:
+				/* Send address MSByte */
+				if (tmp & I2C_STAT_XRDY) {
+					REG(I2C_DXR) = (addr >> 8) & 0xff;
+				} else {
+					REG(I2C_CON) = 0;
+					return(1);
+				}
+
+				tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+				CHECK_NACK();
+				/* No break, fall through */
+			case 1:
+				/* Send address LSByte */
+				if (tmp & I2C_STAT_XRDY) {
+					REG(I2C_DXR) = addr & 0xff;
+				} else {
+					REG(I2C_CON) = 0;
+					return(1);
+				}
+
+				tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK | I2C_STAT_ARDY);
+
+				CHECK_NACK();
+
+				if (!(tmp & I2C_STAT_ARDY)) {
+					REG(I2C_CON) = 0;
+					return(1);
+				}
+		}
+	}
+
+	/* Address phase is over, now read 'len' bytes and stop */
+	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP;
+	REG(I2C_CNT) = len & 0xffff;
+	REG(I2C_SA) = chip;
+	REG(I2C_CON) = tmp;
+
+	for (i = 0; i < len; i++) {
+		tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK | I2C_STAT_ROVR);
+
+		CHECK_NACK();
+
+		if (tmp & I2C_STAT_RRDY) {
+			buf[i] = REG(I2C_DRR);
+		} else {
+			REG(I2C_CON) = 0;
+			return(1);
+		}
+	}
+
+	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
+
+	CHECK_NACK();
+
+	if (!(tmp & I2C_STAT_SCD)) {
+		REG(I2C_CON) = 0;
+		return(1);
+	}
+
+	flush_rx();
+	REG(I2C_STAT) = 0xffff;
+	REG(I2C_CNT) = 0;
+	REG(I2C_CON) = 0;
+
+	return(0);
+}
+
+
+int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+{
+	u_int32_t	tmp;
+	int		i;
+
+	if ((alen < 0) || (alen > 2)) {
+		printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
+		return(1);
+	}
+	if (len < 0) {
+		printf("%s(): bogus length %x\n", __FUNCTION__, len);
+		return(1);
+	}
+
+	if (wait_for_bus()) {return(1);}
+
+	/* Start address phase */
+	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP;
+	REG(I2C_CNT) = (alen == 0) ? len & 0xffff : (len & 0xffff) + alen;
+	REG(I2C_SA) = chip;
+	REG(I2C_CON) = tmp;
+
+	switch (alen) {
+		case 2:
+			/* Send address MSByte */
+			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+			CHECK_NACK();
+
+			if (tmp & I2C_STAT_XRDY) {
+				REG(I2C_DXR) = (addr >> 8) & 0xff;
+			} else {
+				REG(I2C_CON) = 0;
+				return(1);
+			}
+			/* No break, fall through */
+		case 1:
+			/* Send address LSByte */
+			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+			CHECK_NACK();
+
+			if (tmp & I2C_STAT_XRDY) {
+				REG(I2C_DXR) = addr & 0xff;
+			} else {
+				REG(I2C_CON) = 0;
+				return(1);
+			}
+	}
+
+	for (i = 0; i < len; i++) {
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+		CHECK_NACK();
+
+		if (tmp & I2C_STAT_XRDY) {
+			REG(I2C_DXR) = buf[i];
+		} else {
+			return(1);
+		}
+	}
+
+	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
+
+	CHECK_NACK();
+
+	if (!(tmp & I2C_STAT_SCD)) {
+		REG(I2C_CON) = 0;
+		return(1);
+	}
+
+	flush_rx();
+	REG(I2C_STAT) = 0xffff;
+	REG(I2C_CNT) = 0;
+	REG(I2C_CON) = 0;
+
+	return(0);
+}
+
+
+u_int8_t i2c_reg_read(u_int8_t chip, u_int8_t reg)
+{
+	u_int8_t	tmp;
+
+	i2c_read(chip, reg, 1, &tmp, 1);
+	return(tmp);
+}
+
+
+void i2c_reg_write(u_int8_t chip, u_int8_t reg, u_int8_t val)
+{
+	u_int8_t	tmp;
+
+	i2c_write(chip, reg, 1, &tmp, 1);
+}
+
+#endif /* CONFIG_DRIVER_DAVINCI_I2C */
diff --git a/cpu/arm926ejs/davinci/lowlevel_init.S b/cpu/arm926ejs/davinci/lowlevel_init.S
new file mode 100644
index 0000000000000000000000000000000000000000..a87c112eca42e120a4a592430f6c54960baa2489
--- /dev/null
+++ b/cpu/arm926ejs/davinci/lowlevel_init.S
@@ -0,0 +1,707 @@
+/*
+ * Low-level board setup code for TI DaVinci SoC based boards.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Partially based on TI sources, original copyrights follow:
+ */
+
+/*
+ * Board specific setup info
+ *
+ * (C) Copyright 2003
+ * Texas Instruments, <www.ti.com>
+ * Kshitij Gupta <Kshitij@ti.com>
+ *
+ * Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004
+ *
+ * Modified for OMAP 5912 OSK board by Rishi Bhattacharya, Apr 2004
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Modified for DV-EVM board by Rishi Bhattacharya, Apr 2005
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Modified for DV-EVM board by Swaminathan S, Nov 2005
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <config.h>
+
+.globl	lowlevel_init
+lowlevel_init:
+
+	/*-------------------------------------------------------*
+	 * Mask all IRQs by setting all bits in the EINT default *
+	 *-------------------------------------------------------*/
+	mov	r1, $0
+	ldr	r0, =EINT_ENABLE0
+	str	r1, [r0]
+	ldr	r0, =EINT_ENABLE1
+	str	r1, [r0]
+
+	/*------------------------------------------------------*
+	 * Put the GEM in reset					*
+	 *------------------------------------------------------*/
+
+	/* Put the GEM in reset */
+	ldr	r8, PSC_GEM_FLAG_CLEAR
+	ldr	r6, MDCTL_GEM
+	ldr	r7, [r6]
+	and	r7, r7, r8
+	str	r7, [r6]
+
+	/* Enable the Power Domain Transition Command */
+	ldr	r6, PTCMD
+	ldr	r7, [r6]
+	orr	r7, r7, $0x02
+	str	r7, [r6]
+
+	/* Check for Transition Complete(PTSTAT) */
+checkStatClkStopGem:
+	ldr	r6, PTSTAT
+	ldr	r7, [r6]
+	ands	r7, r7, $0x02
+	bne	checkStatClkStopGem
+
+	/* Check for GEM Reset Completion */
+checkGemStatClkStop:
+	ldr	r6, MDSTAT_GEM
+	ldr	r7, [r6]
+	ands	r7, r7, $0x100
+	bne	checkGemStatClkStop
+
+	/* Do this for enabling a WDT initiated reset this is a workaround
+	   for a chip bug.  Not required under normal situations */
+	ldr	r6, P1394
+	mov	r10, $0
+	str	r10, [r6]
+
+	/*------------------------------------------------------*
+	 * Enable L1 & L2 Memories in Fast mode                 *
+	 *------------------------------------------------------*/
+	ldr	r6, DFT_ENABLE
+	mov	r10, $0x01
+	str	r10, [r6]
+
+	ldr	r6, MMARG_BRF0
+	ldr	r10, MMARG_BRF0_VAL
+	str	r10, [r6]
+
+	ldr	r6, DFT_ENABLE
+	mov	r10, $0
+	str	r10, [r6]
+
+	/*------------------------------------------------------*
+	 * DDR2 PLL Initialization			    	*
+	 *------------------------------------------------------*/
+
+	/* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */
+	mov	r10, $0
+	ldr	r6, PLL2_CTL
+	ldr	r7, PLL_CLKSRC_MASK
+	ldr	r8, [r6]
+	and	r8, r8, r7
+	mov	r9, r10, lsl $8
+	orr	r8, r8, r9
+	str	r8, [r6]
+
+	/* Select the PLLEN source */
+	ldr	r7, PLL_ENSRC_MASK
+	and	r8, r8, r7
+	str	r8, [r6]
+
+	/* Bypass the PLL */
+	ldr	r7, PLL_BYPASS_MASK
+	and	r8, r8, r7
+	str	r8, [r6]
+
+	/* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */
+	mov	r10, $0x20
+WaitPPL2Loop:
+	subs	r10, r10, $1
+	bne	WaitPPL2Loop
+
+	/* Reset the PLL */
+	ldr	r7, PLL_RESET_MASK
+	and	r8, r8, r7
+	str	r8, [r6]
+
+	/* Power up the PLL */
+	ldr	r7, PLL_PWRUP_MASK
+	and	r8, r8, r7
+	str	r8, [r6]
+
+	/* Enable the PLL from Disable Mode */
+	ldr	r7, PLL_DISABLE_ENABLE_MASK
+	and	r8, r8, r7
+	str	r8, [r6]
+
+	/* Program the PLL Multiplier */
+	ldr	r6, PLL2_PLLM
+	mov	r2, $0x17	/* 162 MHz */
+	str	r2, [r6]
+
+	/* Program the PLL2 Divisor Value */
+	ldr	r6, PLL2_DIV2
+	mov	r3, $0x01
+	str	r3, [r6]
+
+	/* Program the PLL2 Divisor Value */
+	ldr	r6, PLL2_DIV1
+	mov	r4, $0x0b	/* 54 MHz */
+	str	r4, [r6]
+
+	/* PLL2 DIV2 MMR */
+	ldr	r8, PLL2_DIV_MASK
+	ldr	r6, PLL2_DIV2
+	ldr	r9, [r6]
+	and	r8, r8, r9
+	mov	r9, $0x01
+	mov	r9, r9, lsl $15
+	orr	r8, r8, r9
+	str	r8, [r6]
+
+	/* Program the GOSET bit to take new divider values */
+	ldr	r6, PLL2_PLLCMD
+	ldr	r7, [r6]
+	orr	r7, r7, $0x01
+	str	r7, [r6]
+
+	/* Wait for Done */
+	ldr	r6, PLL2_PLLSTAT
+doneLoop_0:
+	ldr	r7, [r6]
+	ands	r7, r7, $0x01
+	bne	doneLoop_0
+
+	/* PLL2 DIV1 MMR */
+	ldr	r8, PLL2_DIV_MASK
+	ldr	r6, PLL2_DIV1
+	ldr	r9, [r6]
+	and	r8, r8, r9
+	mov	r9, $0x01
+	mov	r9, r9, lsl $15
+	orr	r8, r8, r9
+	str	r8, [r6]
+
+	/* Program the GOSET bit to take new divider values */
+	ldr	r6, PLL2_PLLCMD
+	ldr	r7, [r6]
+	orr	r7, r7, $0x01
+	str	r7, [r6]
+
+	/* Wait for Done */
+	ldr	r6, PLL2_PLLSTAT
+doneLoop:
+	ldr	r7, [r6]
+	ands	r7, r7, $0x01
+	bne	doneLoop
+
+	/* Wait for PLL to Reset Properly */
+	mov	r10, $0x218
+ResetPPL2Loop:
+	subs	r10, r10, $1
+	bne	ResetPPL2Loop
+
+	/* Bring PLL out of Reset */
+	ldr	r6, PLL2_CTL
+	ldr	r8, [r6]
+	orr	r8, r8, $0x08
+	str	r8, [r6]
+
+	/* Wait for PLL to Lock */
+	ldr	r10, PLL_LOCK_COUNT
+PLL2Lock:
+	subs	r10, r10, $1
+	bne	PLL2Lock
+
+	/* Enable the PLL */
+	ldr	r6, PLL2_CTL
+	ldr	r8, [r6]
+	orr	r8, r8, $0x01
+	str	r8, [r6]
+
+	/*------------------------------------------------------*
+	 * Issue Soft Reset to DDR Module			*
+	 *------------------------------------------------------*/
+
+	/* Shut down the DDR2 LPSC Module */
+	ldr	r8, PSC_FLAG_CLEAR
+	ldr	r6, MDCTL_DDR2
+	ldr	r7, [r6]
+	and	r7, r7, r8
+	orr	r7, r7, $0x03
+	str	r7, [r6]
+
+	/* Enable the Power Domain Transition Command */
+	ldr	r6, PTCMD
+	ldr	r7, [r6]
+	orr	r7, r7, $0x01
+	str	r7, [r6]
+
+	/* Check for Transition Complete(PTSTAT) */
+checkStatClkStop:
+	ldr	r6, PTSTAT
+	ldr	r7, [r6]
+	ands	r7, r7, $0x01
+	bne	checkStatClkStop
+
+	/* Check for DDR2 Controller Enable Completion */
+checkDDRStatClkStop:
+	ldr	r6, MDSTAT_DDR2
+	ldr	r7, [r6]
+	and	r7, r7, $0x1f
+	cmp	r7, $0x03
+	bne	checkDDRStatClkStop
+
+	/*------------------------------------------------------*
+	 * Program DDR2 MMRs for 162MHz Setting			*
+	 *------------------------------------------------------*/
+
+	/* Program PHY Control Register */
+	ldr	r6, DDRCTL
+	ldr	r7, DDRCTL_VAL
+	str	r7, [r6]
+
+	/* Program SDRAM Bank Config Register */
+	ldr	r6, SDCFG
+	ldr	r7, SDCFG_VAL
+	str	r7, [r6]
+
+	/* Program SDRAM TIM-0 Config Register */
+	ldr	r6, SDTIM0
+	ldr	r7, SDTIM0_VAL_162MHz
+	str	r7, [r6]
+
+	/* Program SDRAM TIM-1 Config Register */
+	ldr	r6, SDTIM1
+	ldr	r7, SDTIM1_VAL_162MHz
+	str	r7, [r6]
+
+	/* Program the SDRAM Bank Config Control Register */
+	ldr	r10, MASK_VAL
+	ldr	r8, SDCFG
+	ldr	r9, SDCFG_VAL
+	and	r9, r9, r10
+	str	r9, [r8]
+
+	/* Program SDRAM SDREF Config Register */
+	ldr	r6, SDREF
+	ldr	r7, SDREF_VAL
+	str	r7, [r6]
+
+	/*------------------------------------------------------*
+	 * Issue Soft Reset to DDR Module			*
+	 *------------------------------------------------------*/
+
+	/* Issue a Dummy DDR2 read/write */
+	ldr	r8, DDR2_START_ADDR
+	ldr	r7, DUMMY_VAL
+	str	r7, [r8]
+	ldr	r7, [r8]
+
+	/* Shut down the DDR2 LPSC Module */
+	ldr	r8, PSC_FLAG_CLEAR
+	ldr	r6, MDCTL_DDR2
+	ldr	r7, [r6]
+	and	r7, r7, r8
+	orr	r7, r7, $0x01
+	str	r7, [r6]
+
+	/* Enable the Power Domain Transition Command */
+	ldr	r6, PTCMD
+	ldr	r7, [r6]
+	orr	r7, r7, $0x01
+	str	r7, [r6]
+
+	/* Check for Transition Complete(PTSTAT) */
+checkStatClkStop2:
+	ldr	r6, PTSTAT
+	ldr	r7, [r6]
+	ands	r7, r7, $0x01
+	bne	checkStatClkStop2
+
+	/* Check for DDR2 Controller Enable Completion */
+checkDDRStatClkStop2:
+	ldr	r6, MDSTAT_DDR2
+	ldr	r7, [r6]
+	and	r7, r7, $0x1f
+	cmp	r7, $0x01
+	bne	checkDDRStatClkStop2
+
+	/*------------------------------------------------------*
+	 * Turn DDR2 Controller Clocks On			*
+	 *------------------------------------------------------*/
+
+	/* Enable the DDR2 LPSC Module */
+	ldr	r6, MDCTL_DDR2
+	ldr	r7, [r6]
+	orr	r7, r7, $0x03
+	str	r7, [r6]
+
+	/* Enable the Power Domain Transition Command */
+	ldr	r6, PTCMD
+	ldr	r7, [r6]
+	orr	r7, r7, $0x01
+	str	r7, [r6]
+
+	/* Check for Transition Complete(PTSTAT) */
+checkStatClkEn2:
+	ldr	r6, PTSTAT
+	ldr	r7, [r6]
+	ands	r7, r7, $0x01
+	bne	checkStatClkEn2
+
+	/* Check for DDR2 Controller Enable Completion */
+checkDDRStatClkEn2:
+	ldr	r6, MDSTAT_DDR2
+	ldr	r7, [r6]
+	and	r7, r7, $0x1f
+	cmp	r7, $0x03
+	bne	checkDDRStatClkEn2
+
+	/*  DDR Writes and Reads */
+	ldr	r6, CFGTEST
+	mov	r3, $0x01
+	str	r3, [r6]
+
+	/*------------------------------------------------------*
+	 * System PLL Initialization				*
+	 *------------------------------------------------------*/
+
+	/* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */
+	mov	r2, $0
+	ldr	r6, PLL1_CTL
+	ldr	r7, PLL_CLKSRC_MASK
+	ldr	r8, [r6]
+	and	r8, r8, r7
+	mov	r9, r2, lsl $8
+	orr	r8, r8, r9
+	str	r8, [r6]
+
+	/* Select the PLLEN source */
+	ldr	r7, PLL_ENSRC_MASK
+	and	r8, r8, r7
+	str	r8, [r6]
+
+	/* Bypass the PLL */
+	ldr	r7, PLL_BYPASS_MASK
+	and	r8, r8, r7
+	str	r8, [r6]
+
+	/* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */
+	mov	r10, $0x20
+
+WaitLoop:
+	subs	r10, r10, $1
+	bne	WaitLoop
+
+	/* Reset the PLL */
+	ldr	r7, PLL_RESET_MASK
+	and	r8, r8, r7
+	str	r8, [r6]
+
+	/* Disable the PLL */
+	orr	r8, r8, $0x10
+	str	r8, [r6]
+
+	/* Power up the PLL */
+	ldr	r7, PLL_PWRUP_MASK
+	and	r8, r8, r7
+	str	r8, [r6]
+
+	/* Enable the PLL from Disable Mode */
+	ldr	r7, PLL_DISABLE_ENABLE_MASK
+	and	r8, r8, r7
+	str	r8, [r6]
+
+	/* Program the PLL Multiplier */
+	ldr	r6, PLL1_PLLM
+	mov	r3, $0x15	/* For 594MHz */
+	str	r3, [r6]
+
+	/* Wait for PLL to Reset Properly */
+	mov	r10, $0xff
+
+ResetLoop:
+	subs	r10, r10, $1
+	bne	ResetLoop
+
+	/* Bring PLL out of Reset */
+	ldr	r6, PLL1_CTL
+	orr	r8, r8, $0x08
+	str	r8, [r6]
+
+	/* Wait for PLL to Lock */
+	ldr	r10, PLL_LOCK_COUNT
+
+PLL1Lock:
+	subs	r10, r10, $1
+	bne	PLL1Lock
+
+	/* Enable the PLL */
+	orr	r8, r8, $0x01
+	str	r8, [r6]
+
+	nop
+	nop
+	nop
+	nop
+
+	/*------------------------------------------------------*
+	 * AEMIF configuration for NOR Flash (double check)     *
+	 *------------------------------------------------------*/
+	ldr	r0, _PINMUX0
+	ldr	r1, _DEV_SETTING
+	str	r1, [r0]
+
+	ldr	r0, WAITCFG
+	ldr	r1, WAITCFG_VAL
+	ldr	r2, [r0]
+	orr	r2, r2, r1
+	str	r2, [r0]
+
+	ldr	r0, ACFG3
+	ldr	r1, ACFG3_VAL
+	ldr	r2, [r0]
+	and	r1, r2, r1
+	str	r1, [r0]
+
+	ldr	r0, ACFG4
+	ldr	r1, ACFG4_VAL
+	ldr	r2, [r0]
+	and	r1, r2, r1
+	str	r1, [r0]
+
+	ldr	r0, ACFG5
+	ldr	r1, ACFG5_VAL
+	ldr	r2, [r0]
+	and	r1, r2, r1
+	str	r1, [r0]
+
+	/*--------------------------------------*
+	 * VTP manual Calibration               *
+	 *--------------------------------------*/
+	ldr	r0, VTPIOCR
+	ldr	r1, VTP_MMR0
+	str	r1, [r0]
+
+	ldr	r0, VTPIOCR
+	ldr	r1, VTP_MMR1
+	str	r1, [r0]
+
+	/* Wait for 33 VTP CLK cycles.  VRP operates at 27 MHz */
+	ldr	r10, VTP_LOCK_COUNT
+VTPLock:
+	subs	r10, r10, $1
+	bne	VTPLock
+
+	ldr	r6, DFT_ENABLE
+	mov	r10, $0x01
+	str	r10, [r6]
+
+	ldr	r6, DDRVTPR
+	ldr	r7, [r6]
+	and	r7, r7, $0x1f
+	and	r8, r7, $0x3e0
+	orr	r8, r7, r8
+	ldr	r7, VTP_RECAL
+	orr	r8, r7, r8
+	ldr	r7, VTP_EN
+	orr	r8, r7, r8
+	str	r8, [r0]
+
+
+	/* Wait for 33 VTP CLK cycles.  VRP operates at 27 MHz */
+	ldr	r10, VTP_LOCK_COUNT
+VTP1Lock:
+	subs	r10, r10, $1
+	bne	VTP1Lock
+
+	ldr	r1, [r0]
+	ldr	r2, VTP_MASK
+	and	r2, r1, r2
+	str	r2, [r0]
+
+	ldr	r6, DFT_ENABLE
+	mov	r10, $0
+	str	r10, [r6]
+
+	/*
+	 * Call board-specific lowlevel init.
+ 	 * That MUST be present and THAT returns
+	 * back to arch calling code with "mov pc, lr."
+	 */
+	b	dv_board_init
+
+.ltorg
+
+_PINMUX0:
+	.word	0x01c40000		/* Device Configuration Registers */
+_PINMUX1:
+	.word	0x01c40004		/* Device Configuration Registers */
+
+_DEV_SETTING:
+	.word	0x00000c1f
+
+WAITCFG:
+	.word	0x01e00004
+WAITCFG_VAL:
+	.word	0
+ACFG3:
+	.word	0x01e00014
+ACFG3_VAL:
+	.word	0x3ffffffd
+ACFG4:
+	.word	0x01e00018
+ACFG4_VAL:
+	.word	0x3ffffffd
+ACFG5:
+	.word	0x01e0001c
+ACFG5_VAL:
+	.word	0x3ffffffd
+
+MDCTL_DDR2:
+	.word	0x01c41a34
+MDSTAT_DDR2:
+	.word	0x01c41834
+
+PTCMD:
+	.word	0x01c41120
+PTSTAT:
+	.word	0x01c41128
+
+EINT_ENABLE0:
+	.word	0x01c48018
+EINT_ENABLE1:
+	.word	0x01c4801c
+
+PSC_FLAG_CLEAR:
+	.word	0xffffffe0
+PSC_GEM_FLAG_CLEAR:
+	.word	0xfffffeff
+
+/* DDR2 MMR & CONFIGURATION VALUES, 162 MHZ clock */
+DDRCTL:
+	.word	0x200000e4
+DDRCTL_VAL:
+	.word	0x50006405
+SDREF:
+	.word	0x2000000c
+SDREF_VAL:
+	.word	0x000005c3
+SDCFG:
+	.word	0x20000008
+SDCFG_VAL:
+#ifdef	DDR_4BANKS
+	.word	0x00178622
+#elif defined DDR_8BANKS
+	.word	0x00178632
+#else
+#error "Unknown DDR configuration!!!"
+#endif
+SDTIM0:
+	.word	0x20000010
+SDTIM0_VAL_162MHz:
+	.word	0x28923211
+SDTIM1:
+	.word	0x20000014
+SDTIM1_VAL_162MHz:
+	.word	0x0016c722
+VTPIOCR:
+	.word	0x200000f0	/* VTP IO Control register */
+DDRVTPR:
+	.word	0x01c42030	/* DDR VPTR MMR */
+VTP_MMR0:
+	.word	0x201f
+VTP_MMR1:
+	.word	0xa01f
+DFT_ENABLE:
+	.word	0x01c4004c
+VTP_LOCK_COUNT:
+	.word	0x5b0
+VTP_MASK:
+	.word	0xffffdfff
+VTP_RECAL:
+	.word	0x40000
+VTP_EN:
+	.word	0x02000
+CFGTEST:
+	.word	0x80010000
+MASK_VAL:
+	.word	0x00000fff
+
+/* GEM Power Up & LPSC Control Register */
+MDCTL_GEM:
+	.word	0x01c41a9c
+MDSTAT_GEM:
+	.word	0x01c4189c
+
+/* For WDT reset chip bug */
+P1394:
+	.word	0x01c41a20
+
+PLL_CLKSRC_MASK:
+	.word	0xfffffeff	/* Mask the Clock Mode bit */
+PLL_ENSRC_MASK:
+	.word	0xffffffdf	/* Select the PLLEN source */
+PLL_BYPASS_MASK:
+	.word	0xfffffffe	/* Put the PLL in BYPASS */
+PLL_RESET_MASK:
+	.word	0xfffffff7	/* Put the PLL in Reset Mode */
+PLL_PWRUP_MASK:
+	.word	0xfffffffd	/* PLL Power up Mask Bit  */
+PLL_DISABLE_ENABLE_MASK:
+	.word	0xffffffef	/* Enable the PLL from Disable */
+PLL_LOCK_COUNT:
+	.word	0x2000
+
+/* PLL1-SYSTEM PLL MMRs */
+PLL1_CTL:
+	.word	0x01c40900
+PLL1_PLLM:
+	.word	0x01c40910
+
+/* PLL2-SYSTEM PLL MMRs */
+PLL2_CTL:
+	.word	0x01c40d00
+PLL2_PLLM:
+	.word	0x01c40d10
+PLL2_DIV1:
+	.word	0x01c40d18
+PLL2_DIV2:
+	.word	0x01c40d1c
+PLL2_PLLCMD:
+	.word	0x01c40d38
+PLL2_PLLSTAT:
+	.word	0x01c40d3c
+PLL2_DIV_MASK:
+	.word	0xffff7fff
+
+MMARG_BRF0:
+	.word	0x01c42010	/* BRF margin mode 0 (R/W)*/
+MMARG_BRF0_VAL:
+	.word	0x00444400
+
+DDR2_START_ADDR:
+	.word	0x80000000
+DUMMY_VAL:
+	.word	0xa55aa55a
diff --git a/cpu/arm926ejs/davinci/lxt972.c b/cpu/arm926ejs/davinci/lxt972.c
new file mode 100644
index 0000000000000000000000000000000000000000..6eeb6e5ee9274821fc6a64ba8625c3bd2dbb337a
--- /dev/null
+++ b/cpu/arm926ejs/davinci/lxt972.c
@@ -0,0 +1,142 @@
+/*
+ * Intel LXT971/LXT972 PHY Driver for TI DaVinci
+ * (TMS320DM644x) based boards.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * --------------------------------------------------------
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <common.h>
+#include <net.h>
+#include <lxt971a.h>
+#include <asm/arch/emac_defs.h>
+
+#ifdef CONFIG_DRIVER_TI_EMAC
+
+#ifdef CONFIG_CMD_NET
+
+int lxt972_is_phy_connected(int phy_addr)
+{
+	u_int16_t	id1, id2;
+
+	if (!dm644x_eth_phy_read(phy_addr, PHY_COMMON_ID1, &id1))
+		return(0);
+	if (!dm644x_eth_phy_read(phy_addr, PHY_COMMON_ID2, &id2))
+		return(0);
+
+	if ((id1 == (0x0013)) && ((id2  & 0xfff0) == 0x78e0))
+		return(1);
+
+	return(0);
+}
+
+int lxt972_get_link_speed(int phy_addr)
+{
+	u_int16_t		stat1, tmp;
+	volatile emac_regs*	emac = (emac_regs *)EMAC_BASE_ADDR;
+
+	if (!dm644x_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1))
+		return(0);
+
+	if (!(stat1 & PHY_LXT971_STAT2_LINK))	/* link up? */
+		return(0);
+
+	if (!dm644x_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp))
+		return(0);
+
+	tmp |= PHY_LXT971_DIG_CFG_MII_DRIVE;
+
+	dm644x_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp);
+	/* Read back */
+	if (!dm644x_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp))
+		return(0);
+
+
+	/* Speed doesn't matter, there is no setting for it in EMAC... */
+	if (stat1 & PHY_LXT971_STAT2_100BTX) {
+		if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) {
+			/* set DM644x EMAC for Full Duplex  */
+			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
+		} else {
+			/*set DM644x EMAC for Half Duplex  */
+			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
+		}
+
+		return(1);
+	} else {
+		if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) {
+			/* set DM644x EMAC for Full Duplex  */
+			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
+		} else {
+			/*set DM644x EMAC for Half Duplex  */
+			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
+		}
+
+		return(1);
+	}
+
+	return(0);
+}
+
+
+int lxt972_init_phy(int phy_addr)
+{
+	int	ret = 1;
+
+	if (!lxt972_get_link_speed(phy_addr)) {
+		/* Try another time */
+		ret = lxt972_get_link_speed(phy_addr);
+	}
+
+	/* Disable PHY Interrupts */
+	dm644x_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0);
+
+	return(ret);
+}
+
+
+int lxt972_auto_negotiate(int phy_addr)
+{
+	u_int16_t	tmp;
+
+
+	if (!dm644x_eth_phy_read(phy_addr, PHY_COMMON_CTRL, &tmp))
+		return(0);
+
+	/* Restart Auto_negotiation  */
+	tmp |= PHY_COMMON_CTRL_RES_AUTO;
+	dm644x_eth_phy_write(phy_addr, PHY_COMMON_CTRL, tmp);
+
+	/*check AutoNegotiate complete */
+	udelay (10000);
+	if (!dm644x_eth_phy_read(phy_addr, PHY_COMMON_STAT, &tmp))
+		return(0);
+
+	if (!(tmp & PHY_COMMON_STAT_AN_COMP))
+		return(0);
+
+	return (lxt972_get_link_speed(phy_addr));
+}
+
+#endif	/* CONFIG_CMD_NET */
+
+#endif	/* CONFIG_DRIVER_ETHER */
diff --git a/cpu/arm926ejs/davinci/nand.c b/cpu/arm926ejs/davinci/nand.c
new file mode 100644
index 0000000000000000000000000000000000000000..127be9fcd4396d1b9918e467fc12258572adb96b
--- /dev/null
+++ b/cpu/arm926ejs/davinci/nand.c
@@ -0,0 +1,389 @@
+/*
+ * NAND driver for TI DaVinci based boards.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Based on Linux DaVinci NAND driver by TI. Original copyright follows:
+ */
+
+/*
+ *
+ * linux/drivers/mtd/nand/nand_davinci.c
+ *
+ * NAND Flash Driver
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+ *
+ *  Overview:
+ *   This is a device driver for the NAND flash device found on the
+ *   DaVinci board which utilizes the Samsung k9k2g08 part.
+ *
+ Modifications:
+ ver. 1.0: Feb 2005, Vinod/Sudhakar
+ -
+ *
+ */
+
+#include <common.h>
+
+#ifdef CFG_USE_NAND
+#if !defined(CFG_NAND_LEGACY)
+
+#include <nand.h>
+#include <asm/arch/nand_defs.h>
+#include <asm/arch/emif_defs.h>
+
+extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
+
+static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+	struct		nand_chip *this = mtd->priv;
+	u_int32_t	IO_ADDR_W = (u_int32_t)this->IO_ADDR_W;
+
+	IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
+
+	switch (cmd) {
+		case NAND_CTL_SETCLE:
+			IO_ADDR_W |= MASK_CLE;
+			break;
+		case NAND_CTL_SETALE:
+			IO_ADDR_W |= MASK_ALE;
+			break;
+	}
+
+	this->IO_ADDR_W = (void *)IO_ADDR_W;
+}
+
+/* Set WP on deselect, write enable on select */
+static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
+{
+#define GPIO_SET_DATA01	0x01c67018
+#define GPIO_CLR_DATA01	0x01c6701c
+#define GPIO_NAND_WP	(1 << 4)
+#ifdef SONATA_BOARD_GPIOWP
+	if (chip < 0) {
+		REG(GPIO_CLR_DATA01) |= GPIO_NAND_WP;
+	} else {
+		REG(GPIO_SET_DATA01) |= GPIO_NAND_WP;
+	}
+#endif
+}
+
+#ifdef CFG_NAND_HW_ECC
+#ifdef CFG_NAND_LARGEPAGE
+static struct nand_oobinfo davinci_nand_oobinfo = {
+	.useecc = MTD_NANDECC_AUTOPLACE,
+	.eccbytes = 12,
+	.eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58},
+	.oobfree = { {2, 6}, {12, 12}, {28, 12}, {44, 12}, {60, 4} }
+};
+#elif defined(CFG_NAND_SMALLPAGE)
+static struct nand_oobinfo davinci_nand_oobinfo = {
+	.useecc = MTD_NANDECC_AUTOPLACE,
+	.eccbytes = 3,
+	.eccpos = {0, 1, 2},
+	.oobfree = { {6, 2}, {8, 8} }
+};
+#else
+#error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!"
+#endif
+
+static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+	emifregs	emif_addr;
+	int		dummy;
+
+	emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
+
+	dummy = emif_addr->NANDF1ECC;
+	dummy = emif_addr->NANDF2ECC;
+	dummy = emif_addr->NANDF3ECC;
+	dummy = emif_addr->NANDF4ECC;
+
+	emif_addr->NANDFCR |= (1 << 8);
+}
+
+static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region)
+{
+	u_int32_t	ecc = 0;
+	emifregs	emif_base_addr;
+
+	emif_base_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
+
+	if (region == 1)
+		ecc = emif_base_addr->NANDF1ECC;
+	else if (region == 2)
+		ecc = emif_base_addr->NANDF2ECC;
+	else if (region == 3)
+		ecc = emif_base_addr->NANDF3ECC;
+	else if (region == 4)
+		ecc = emif_base_addr->NANDF4ECC;
+
+	return(ecc);
+}
+
+static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+{
+	u_int32_t		tmp;
+	int			region, n;
+	struct nand_chip	*this = mtd->priv;
+
+	n = (this->eccmode == NAND_ECC_HW12_2048) ? 4 : 1;
+
+	region = 1;
+	while (n--) {
+		tmp = nand_davinci_readecc(mtd, region);
+		*ecc_code++ = tmp;
+		*ecc_code++ = tmp >> 16;
+		*ecc_code++ = ((tmp >> 8) & 0x0f) | ((tmp >> 20) & 0xf0);
+		region++;
+	}
+	return(0);
+}
+
+static void nand_davinci_gen_true_ecc(u_int8_t *ecc_buf)
+{
+	u_int32_t	tmp = ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xf0) << 20) | ((ecc_buf[2] & 0x0f) << 8);
+
+	ecc_buf[0] = ~(P64o(tmp) | P64e(tmp) | P32o(tmp) | P32e(tmp) | P16o(tmp) | P16e(tmp) | P8o(tmp) | P8e(tmp));
+	ecc_buf[1] = ~(P1024o(tmp) | P1024e(tmp) | P512o(tmp) | P512e(tmp) | P256o(tmp) | P256e(tmp) | P128o(tmp) | P128e(tmp));
+	ecc_buf[2] = ~( P4o(tmp) | P4e(tmp) | P2o(tmp) | P2e(tmp) | P1o(tmp) | P1e(tmp) | P2048o(tmp) | P2048e(tmp));
+}
+
+static int nand_davinci_compare_ecc(u_int8_t *ecc_nand, u_int8_t *ecc_calc, u_int8_t *page_data)
+{
+	u_int32_t	i;
+	u_int8_t	tmp0_bit[8], tmp1_bit[8], tmp2_bit[8];
+	u_int8_t	comp0_bit[8], comp1_bit[8], comp2_bit[8];
+	u_int8_t	ecc_bit[24];
+	u_int8_t	ecc_sum = 0;
+	u_int8_t	find_bit = 0;
+	u_int32_t	find_byte = 0;
+	int		is_ecc_ff;
+
+	is_ecc_ff = ((*ecc_nand == 0xff) && (*(ecc_nand + 1) == 0xff) && (*(ecc_nand + 2) == 0xff));
+
+	nand_davinci_gen_true_ecc(ecc_nand);
+	nand_davinci_gen_true_ecc(ecc_calc);
+
+	for (i = 0; i <= 2; i++) {
+		*(ecc_nand + i) = ~(*(ecc_nand + i));
+		*(ecc_calc + i) = ~(*(ecc_calc + i));
+	}
+
+	for (i = 0; i < 8; i++) {
+		tmp0_bit[i] = *ecc_nand % 2;
+		*ecc_nand = *ecc_nand / 2;
+	}
+
+	for (i = 0; i < 8; i++) {
+		tmp1_bit[i] = *(ecc_nand + 1) % 2;
+		*(ecc_nand + 1) = *(ecc_nand + 1) / 2;
+	}
+
+	for (i = 0; i < 8; i++) {
+		tmp2_bit[i] = *(ecc_nand + 2) % 2;
+		*(ecc_nand + 2) = *(ecc_nand + 2) / 2;
+	}
+
+	for (i = 0; i < 8; i++) {
+		comp0_bit[i] = *ecc_calc % 2;
+		*ecc_calc = *ecc_calc / 2;
+	}
+
+	for (i = 0; i < 8; i++) {
+		comp1_bit[i] = *(ecc_calc + 1) % 2;
+		*(ecc_calc + 1) = *(ecc_calc + 1) / 2;
+	}
+
+	for (i = 0; i < 8; i++) {
+		comp2_bit[i] = *(ecc_calc + 2) % 2;
+		*(ecc_calc + 2) = *(ecc_calc + 2) / 2;
+	}
+
+	for (i = 0; i< 6; i++)
+		ecc_bit[i] = tmp2_bit[i + 2] ^ comp2_bit[i + 2];
+
+	for (i = 0; i < 8; i++)
+		ecc_bit[i + 6] = tmp0_bit[i] ^ comp0_bit[i];
+
+	for (i = 0; i < 8; i++)
+		ecc_bit[i + 14] = tmp1_bit[i] ^ comp1_bit[i];
+
+	ecc_bit[22] = tmp2_bit[0] ^ comp2_bit[0];
+	ecc_bit[23] = tmp2_bit[1] ^ comp2_bit[1];
+
+	for (i = 0; i < 24; i++)
+		ecc_sum += ecc_bit[i];
+
+	switch (ecc_sum) {
+		case 0:
+			/* Not reached because this function is not called if
+			   ECC values are equal */
+			return 0;
+		case 1:
+			/* Uncorrectable error */
+			DEBUG (MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR 1\n");
+			return(-1);
+		case 12:
+			/* Correctable error */
+			find_byte = (ecc_bit[23] << 8) +
+				(ecc_bit[21] << 7) +
+				(ecc_bit[19] << 6) +
+				(ecc_bit[17] << 5) +
+				(ecc_bit[15] << 4) +
+				(ecc_bit[13] << 3) +
+				(ecc_bit[11] << 2) +
+				(ecc_bit[9]  << 1) +
+				ecc_bit[7];
+
+			find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1];
+
+			DEBUG (MTD_DEBUG_LEVEL0, "Correcting single bit ECC error at offset: %d, bit: %d\n", find_byte, find_bit);
+
+			page_data[find_byte] ^= (1 << find_bit);
+
+			return(0);
+		default:
+			if (is_ecc_ff) {
+				if (ecc_calc[0] == 0 && ecc_calc[1] == 0 && ecc_calc[2] == 0)
+					return(0);
+			}
+			DEBUG (MTD_DEBUG_LEVEL0, "UNCORRECTED_ERROR default\n");
+			return(-1);
+	}
+}
+
+static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
+{
+	struct nand_chip	*this;
+	int			block_count = 0, i, rc;
+
+	this = mtd->priv;
+	block_count = (this->eccmode == NAND_ECC_HW12_2048) ? 4 : 1;
+	for (i = 0; i < block_count; i++) {
+		if (memcmp(read_ecc, calc_ecc, 3) != 0) {
+			rc = nand_davinci_compare_ecc(read_ecc, calc_ecc, dat);
+			if (rc < 0) {
+				return(rc);
+			}
+		}
+		read_ecc += 3;
+		calc_ecc += 3;
+		dat += 512;
+	}
+	return(0);
+}
+#endif
+
+static int nand_davinci_dev_ready(struct mtd_info *mtd)
+{
+	emifregs	emif_addr;
+
+	emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
+
+	return(emif_addr->NANDFSR & 0x1);
+}
+
+static int nand_davinci_waitfunc(struct mtd_info *mtd, struct nand_chip *this, int state)
+{
+	while(!nand_davinci_dev_ready(mtd)) {;}
+	*NAND_CE0CLE = NAND_STATUS;
+	return(*NAND_CE0DATA);
+}
+
+static void nand_flash_init(void)
+{
+	u_int32_t	acfg1 = 0x3ffffffc;
+	u_int32_t	acfg2 = 0x3ffffffc;
+	u_int32_t	acfg3 = 0x3ffffffc;
+	u_int32_t	acfg4 = 0x3ffffffc;
+	emifregs	emif_regs;
+
+	/*------------------------------------------------------------------*
+	 *  NAND FLASH CHIP TIMEOUT @ 459 MHz                               *
+	 *                                                                  *
+	 *  AEMIF.CLK freq   = PLL1/6 = 459/6 = 76.5 MHz                    *
+	 *  AEMIF.CLK period = 1/76.5 MHz = 13.1 ns                         *
+	 *                                                                  *
+	 *------------------------------------------------------------------*/
+	 acfg1 = 0
+	 	| (0 << 31 )	/* selectStrobe */
+	 	| (0 << 30 )	/* extWait */
+	 	| (1 << 26 )	/* writeSetup	10 ns */
+	 	| (3 << 20 )	/* writeStrobe	40 ns */
+	 	| (1 << 17 )	/* writeHold	10 ns */
+	 	| (1 << 13 )	/* readSetup	10 ns */
+	 	| (5 << 7 )	/* readStrobe	60 ns */
+	 	| (1 << 4 )	/* readHold	10 ns */
+	 	| (3 << 2 )	/* turnAround	?? ns */
+	 	| (0 << 0 )	/* asyncSize	8-bit bus */
+	 	;
+
+	emif_regs = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
+
+	emif_regs->AWCCR |= 0x10000000;
+	emif_regs->AB1CR = acfg1;	/* 0x08244128 */;
+	emif_regs->AB2CR = acfg2;
+	emif_regs->AB3CR = acfg3;
+	emif_regs->AB4CR = acfg4;
+	emif_regs->NANDFCR = 0x00000101;
+}
+
+int board_nand_init(struct nand_chip *nand)
+{
+	nand->IO_ADDR_R   = (void  __iomem *)NAND_CE0DATA;
+	nand->IO_ADDR_W   = (void  __iomem *)NAND_CE0DATA;
+	nand->chip_delay  = 0;
+	nand->select_chip = nand_davinci_select_chip;
+#ifdef CFG_NAND_USE_FLASH_BBT
+	nand->options	  = NAND_USE_FLASH_BBT;
+#endif
+#ifdef CFG_NAND_HW_ECC
+#ifdef CFG_NAND_LARGEPAGE
+	nand->eccmode     = NAND_ECC_HW12_2048;
+#elif defined(CFG_NAND_SMALLPAGE)
+	nand->eccmode     = NAND_ECC_HW3_512;
+#else
+#error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!"
+#endif
+	nand->autooob	  = &davinci_nand_oobinfo;
+	nand->calculate_ecc = nand_davinci_calculate_ecc;
+	nand->correct_data  = nand_davinci_correct_data;
+	nand->enable_hwecc  = nand_davinci_enable_hwecc;
+#else
+	nand->eccmode     = NAND_ECC_SOFT;
+#endif
+
+	/* Set address of hardware control function */
+	nand->hwcontrol = nand_davinci_hwcontrol;
+
+	nand->dev_ready = nand_davinci_dev_ready;
+	nand->waitfunc = nand_davinci_waitfunc;
+
+	nand_flash_init();
+
+	return(0);
+}
+
+#else
+#error "U-Boot legacy NAND support not available for DaVinci chips"
+#endif
+#endif	/* CFG_USE_NAND */
diff --git a/cpu/arm926ejs/davinci/reset.S b/cpu/arm926ejs/davinci/reset.S
new file mode 100644
index 0000000000000000000000000000000000000000..a687d44035c45821ebf318027be7021a2328f10b
--- /dev/null
+++ b/cpu/arm926ejs/davinci/reset.S
@@ -0,0 +1,77 @@
+/*
+ * Processor reset using WDT for TI TMS320DM644x SoC.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * -----------------------------------------------------
+ *
+ * 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
+ */
+
+.globl reset_cpu
+reset_cpu:
+	ldr	r0, WDT_TGCR
+	mov	r1, $0x08
+	str	r1, [r0]
+	ldr	r1, [r0]
+	orr	r1, r1, $0x03
+	str	r1, [r0]
+	mov	r1, $0
+	ldr	r0, WDT_TIM12
+	str	r1, [r0]
+	ldr	r0, WDT_TIM34
+	str	r1, [r0]
+	ldr	r0, WDT_PRD12
+	str	r1, [r0]
+	ldr	r0, WDT_PRD34
+	str	r1, [r0]
+	ldr	r0, WDT_TCR
+	ldr	r1, [r0]
+	orr	r1, r1, $0x40
+	str	r1, [r0]
+	ldr	r0, WDT_WDTCR
+	ldr	r1, [r0]
+	orr	r1, r1, $0x4000
+	str	r1, [r0]
+	ldr	r1, WDTCR_VAL1
+	str	r1, [r0]
+	ldr	r1, WDTCR_VAL2
+	str	r1, [r0]
+	nop
+	nop
+	nop
+	nop
+reset_cpu_loop:
+	b	reset_cpu_loop
+
+WDT_TGCR:
+	.word	0x01c21c24
+WDT_TIM12:
+	.word	0x01c21c10
+WDT_TIM34:
+	.word	0x01c21c14
+WDT_PRD12:
+	.word	0x01c21c18
+WDT_PRD34:
+	.word	0x01c21c1c
+WDT_TCR:
+	.word	0x01c21c20
+WDT_WDTCR:
+	.word	0x01c21c28
+WDTCR_VAL1:
+	.word	0xa5c64000
+WDTCR_VAL2:
+	.word	0xda7e4000
diff --git a/cpu/arm926ejs/davinci/timer.c b/cpu/arm926ejs/davinci/timer.c
new file mode 100644
index 0000000000000000000000000000000000000000..c6b1dda51fcf86b782c78abd8aab23655d07ce5e
--- /dev/null
+++ b/cpu/arm926ejs/davinci/timer.c
@@ -0,0 +1,165 @@
+/*
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <common.h>
+#include <arm926ejs.h>
+
+typedef volatile struct {
+	u_int32_t	pid12;
+	u_int32_t	emumgt_clksped;
+	u_int32_t	gpint_en;
+	u_int32_t	gpdir_dat;
+	u_int32_t	tim12;
+	u_int32_t	tim34;
+	u_int32_t	prd12;
+	u_int32_t	prd34;
+	u_int32_t	tcr;
+	u_int32_t	tgcr;
+	u_int32_t	wdtcr;
+	u_int32_t	tlgc;
+	u_int32_t	tlmr;
+} davinci_timer;
+
+davinci_timer		*timer = (davinci_timer *)CFG_TIMERBASE;
+
+#define TIMER_LOAD_VAL	(CFG_HZ_CLOCK / CFG_HZ)
+#define READ_TIMER	timer->tim34
+
+static ulong timestamp;
+static ulong lastinc;
+
+int timer_init(void)
+{
+	/* We are using timer34 in unchained 32-bit mode, full speed */
+	timer->tcr = 0x0;
+	timer->tgcr = 0x0;
+	timer->tgcr = 0x06;
+	timer->tim34 = 0x0;
+	timer->prd34 = TIMER_LOAD_VAL;
+	lastinc = 0;
+	timer->tcr = 0x80 << 16;
+	timestamp = 0;
+
+	return(0);
+}
+
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+	return(get_timer_masked() - base);
+}
+
+void set_timer(ulong t)
+{
+	timestamp = t;
+}
+
+void udelay(unsigned long usec)
+{
+	udelay_masked(usec);
+}
+
+void reset_timer_masked(void)
+{
+	lastinc = READ_TIMER;
+	timestamp = 0;
+}
+
+ulong get_timer_raw(void)
+{
+	ulong now = READ_TIMER;
+
+	if (now >= lastinc) {
+		/* normal mode */
+		timestamp += now - lastinc;
+	} else {
+		/* overflow ... */
+		timestamp += now + TIMER_LOAD_VAL - lastinc;
+	}
+	lastinc = now;
+	return timestamp;
+}
+
+ulong get_timer_masked(void)
+{
+	return(get_timer_raw() / TIMER_LOAD_VAL);
+}
+
+void udelay_masked(unsigned long usec)
+{
+	ulong tmo;
+	ulong endtime;
+	signed long diff;
+
+	tmo = CFG_HZ_CLOCK / 1000;
+	tmo *= usec;
+	tmo /= 1000;
+
+	endtime = get_timer_raw() + tmo;
+
+	do {
+		ulong now = get_timer_raw();
+		diff = endtime - now;
+	} while (diff >= 0);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+	return(get_timer(0));
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+	ulong tbclk;
+
+	tbclk = CFG_HZ;
+	return(tbclk);
+}
diff --git a/cpu/mpc5xxx/Makefile b/cpu/mpc5xxx/Makefile
index 235adb7c04e60fc61aba0dcea2285b1d4170a598..312b0bfc6cc8a64c3dbc5a3d37fe4b2052fb3d32 100644
--- a/cpu/mpc5xxx/Makefile
+++ b/cpu/mpc5xxx/Makefile
@@ -28,7 +28,7 @@ LIB	= $(obj)lib$(CPU).a
 START	= start.o
 SOBJS	= io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o
 COBJS	= i2c.o traps.o cpu.o cpu_init.o fec.o ide.o interrupts.o \
-	  loadtask.o pci_mpc5200.o serial.o speed.o usb_ohci.o
+	  loadtask.o pci_mpc5200.o serial.o speed.o usb_ohci.o usb.o
 
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/mpc5xxx/usb.c b/cpu/mpc5xxx/usb.c
new file mode 100644
index 0000000000000000000000000000000000000000..ce709fc652c91d76234d6c762a36b948994b9140
--- /dev/null
+++ b/cpu/mpc5xxx/usb.c
@@ -0,0 +1,54 @@
+/*
+ * (C) Copyright 2007
+ * Markus Klotzbuecher, DENX Software Engineering <mk@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <common.h>
+
+#if defined(CONFIG_USB_OHCI_NEW) && defined(CFG_USB_OHCI_CPU_INIT)
+
+#include <mpc5xxx.h>
+
+int usb_cpu_init()
+{
+	/* Set the USB Clock						     */
+	*(vu_long *)MPC5XXX_CDM_48_FDC = CONFIG_USB_CLOCK;
+
+	/* remove all USB bits first before ORing in ours */
+	*(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~0x00807000;
+
+	/* Activate USB port						     */
+	*(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= CONFIG_USB_CONFIG;
+
+	return 0;
+}
+
+int usb_cpu_stop()
+{
+	return 0;
+}
+
+int usb_cpu_init_fail()
+{
+	return 0;
+}
+
+#endif /* defined(CONFIG_USB_OHCI) && defined(CFG_USB_OHCI_CPU_INIT) */
diff --git a/cpu/mpc83xx/Makefile b/cpu/mpc83xx/Makefile
index bb96f774fe4e3cc795c6aa1bd0742a458fd028a5..232997005102a39036304f01d3c709d58976b475 100644
--- a/cpu/mpc83xx/Makefile
+++ b/cpu/mpc83xx/Makefile
@@ -29,7 +29,7 @@ LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
 COBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o \
-	  spd_sdram.o qe_io.o pci.o
+	  spd_sdram.o ecc.o qe_io.o pci.o
 
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c
index 841fe82428d4c9b5509ee3f6fe63923c02b946a6..adf80830103f00be13f1cd2ce52c21425923b11e 100644
--- a/cpu/mpc83xx/cpu.c
+++ b/cpu/mpc83xx/cpu.c
@@ -33,8 +33,7 @@
 #include <asm/processor.h>
 #if defined(CONFIG_OF_FLAT_TREE)
 #include <ft_build.h>
-#endif
-#if defined(CONFIG_OF_LIBFDT)
+#elif defined(CONFIG_OF_LIBFDT)
 #include <libfdt.h>
 #include <libfdt_env.h>
 #endif
@@ -113,12 +112,14 @@ int checkcpu(void)
 	case SPR_8360E_REV11:
 	case SPR_8360E_REV12:
 	case SPR_8360E_REV20:
+	case SPR_8360E_REV21:
 		puts("MPC8360E, ");
 		break;
 	case SPR_8360_REV10:
 	case SPR_8360_REV11:
 	case SPR_8360_REV12:
 	case SPR_8360_REV20:
+	case SPR_8360_REV21:
 		puts("MPC8360, ");
 		break;
 	case SPR_8323E_REV10:
@@ -150,7 +151,8 @@ int checkcpu(void)
 		puts("MPC8313E, ");
 		break;
 	default:
-		puts("Rev: Unknown revision number.\nWarning: Unsupported cpu revision!\n");
+		printf("Rev: Unknown revision number:%08x\n"
+			"Warning: Unsupported cpu revision!\n",spridr);
 		return 0;
 	}
 
@@ -329,154 +331,167 @@ void watchdog_reset (void)
 /*
  * "Setter" functions used to add/modify FDT entries.
  */
-static int fdt_set_eth0(void *fdt, int nodeoffset, const char *name, bd_t *bd)
+static int fdt_set_eth0(void *blob, int nodeoffset, const char *name, bd_t *bd)
 {
 	/*
 	 * Fix it up if it exists, don't create it if it doesn't exist.
 	 */
-	if (fdt_get_property(fdt, nodeoffset, name, 0)) {
-		return fdt_setprop(fdt, nodeoffset, name, bd->bi_enetaddr, 6);
+	if (fdt_get_property(blob, nodeoffset, name, 0)) {
+		return fdt_setprop(blob, nodeoffset, name, bd->bi_enetaddr, 6);
 	}
-	return -FDT_ERR_NOTFOUND;
+	return 0;
 }
 #ifdef CONFIG_HAS_ETH1
 /* second onboard ethernet port */
-static int fdt_set_eth1(void *fdt, int nodeoffset, const char *name, bd_t *bd)
+static int fdt_set_eth1(void *blob, int nodeoffset, const char *name, bd_t *bd)
 {
 	/*
 	 * Fix it up if it exists, don't create it if it doesn't exist.
 	 */
-	if (fdt_get_property(fdt, nodeoffset, name, 0)) {
-		return fdt_setprop(fdt, nodeoffset, name, bd->bi_enet1addr, 6);
+	if (fdt_get_property(blob, nodeoffset, name, 0)) {
+		return fdt_setprop(blob, nodeoffset, name, bd->bi_enet1addr, 6);
 	}
-	return -FDT_ERR_NOTFOUND;
+	return 0;
 }
 #endif
 #ifdef CONFIG_HAS_ETH2
 /* third onboard ethernet port */
-static int fdt_set_eth2(void *fdt, int nodeoffset, const char *name, bd_t *bd)
+static int fdt_set_eth2(void *blob, int nodeoffset, const char *name, bd_t *bd)
 {
 	/*
 	 * Fix it up if it exists, don't create it if it doesn't exist.
 	 */
-	if (fdt_get_property(fdt, nodeoffset, name, 0)) {
-		return fdt_setprop(fdt, nodeoffset, name, bd->bi_enet2addr, 6);
+	if (fdt_get_property(blob, nodeoffset, name, 0)) {
+		return fdt_setprop(blob, nodeoffset, name, bd->bi_enet2addr, 6);
 	}
-	return -FDT_ERR_NOTFOUND;
+	return 0;
 }
 #endif
 #ifdef CONFIG_HAS_ETH3
 /* fourth onboard ethernet port */
-static int fdt_set_eth3(void *fdt, int nodeoffset, const char *name, bd_t *bd)
+static int fdt_set_eth3(void *blob, int nodeoffset, const char *name, bd_t *bd)
 {
 	/*
 	 * Fix it up if it exists, don't create it if it doesn't exist.
 	 */
-	if (fdt_get_property(fdt, nodeoffset, name, 0)) {
-		return fdt_setprop(fdt, nodeoffset, name, bd->bi_enet3addr, 6);
+	if (fdt_get_property(blob, nodeoffset, name, 0)) {
+		return fdt_setprop(blob, nodeoffset, name, bd->bi_enet3addr, 6);
 	}
-	return -FDT_ERR_NOTFOUND;
+	return 0;
 }
 #endif
 
-static int fdt_set_busfreq(void *fdt, int nodeoffset, const char *name, bd_t *bd)
+static int fdt_set_busfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
 {
 	u32  tmp;
 	/*
 	 * Create or update the property.
 	 */
 	tmp = cpu_to_be32(bd->bi_busfreq);
-	return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
+	return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
+}
+
+static int fdt_set_tbfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
+{
+	u32  tmp;
+	/*
+	 * Create or update the property.
+	 */
+	tmp = cpu_to_be32(OF_TBCLK);
+	return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
 }
 
+
 /*
- * Fixups to the fdt.  If "create" is TRUE, the node is created
- * unconditionally.  If "create" is FALSE, the node is updated
- * only if it already exists.
+ * Fixups to the fdt.
  */
 static const struct {
 	char *node;
 	char *prop;
-	int (*set_fn)(void *fdt, int nodeoffset, const char *name, bd_t *bd);
+	int (*set_fn)(void *blob, int nodeoffset, const char *name, bd_t *bd);
 } fixup_props[] = {
 	{	"/cpus/" OF_CPU,
-		 "bus-frequency",
-		fdt_set_busfreq
+		"timebase-frequency",
+		fdt_set_tbfreq
 	},
-	{	"/cpus/" OF_SOC,
+	{	"/cpus/" OF_CPU,
 		"bus-frequency",
 		fdt_set_busfreq
 	},
-	{	"/" OF_SOC "/serial@4500/",
+	{	"/cpus/" OF_CPU,
+		"clock-frequency",
+		fdt_set_busfreq
+	},
+	{	"/" OF_SOC "/serial@4500",
 		"clock-frequency",
 		fdt_set_busfreq
 	},
-	{	"/" OF_SOC "/serial@4600/",
+	{	"/" OF_SOC "/serial@4600",
 		"clock-frequency",
 		fdt_set_busfreq
 	},
 #ifdef CONFIG_TSEC1
-	{	"/" OF_SOC "/ethernet@24000,
+	{	"/" OF_SOC "/ethernet@24000",
 		"mac-address",
 		fdt_set_eth0
 	},
-	{	"/" OF_SOC "/ethernet@24000,
+	{	"/" OF_SOC "/ethernet@24000",
 		"local-mac-address",
 		fdt_set_eth0
 	},
 #endif
 #ifdef CONFIG_TSEC2
-	{	"/" OF_SOC "/ethernet@25000,
+	{	"/" OF_SOC "/ethernet@25000",
 		"mac-address",
 		fdt_set_eth1
 	},
-	{	"/" OF_SOC "/ethernet@25000,
+	{	"/" OF_SOC "/ethernet@25000",
 		"local-mac-address",
 		fdt_set_eth1
 	},
 #endif
 #ifdef CONFIG_UEC_ETH1
 #if CFG_UEC1_UCC_NUM == 0  /* UCC1 */
-	{	"/" OF_QE "/ucc@2000/mac-address",
+	{	"/" OF_QE "/ucc@2000",
 		"mac-address",
 		fdt_set_eth0
 	},
-	{	"/" OF_QE "/ucc@2000/mac-address",
+	{	"/" OF_QE "/ucc@2000",
 		"local-mac-address",
 		fdt_set_eth0
 	},
 #elif CFG_UEC1_UCC_NUM == 2  /* UCC3 */
-	{	"/" OF_QE "/ucc@2200/mac-address",
+	{	"/" OF_QE "/ucc@2200",
 		"mac-address",
 		fdt_set_eth0
 	},
-	{	"/" OF_QE "/ucc@2200/mac-address",
+	{	"/" OF_QE "/ucc@2200",
 		"local-mac-address",
 		fdt_set_eth0
 	},
 #endif
-#endif
+#endif /* CONFIG_UEC_ETH1 */
 #ifdef CONFIG_UEC_ETH2
 #if CFG_UEC2_UCC_NUM == 1  /* UCC2 */
-	{	"/" OF_QE "/ucc@3000/mac-address",
+	{	"/" OF_QE "/ucc@3000",
 		"mac-address",
 		fdt_set_eth1
 	},
-	{	"/" OF_QE "/ucc@3000/mac-address",
+	{	"/" OF_QE "/ucc@3000",
 		"local-mac-address",
 		fdt_set_eth1
 	},
 #elif CFG_UEC1_UCC_NUM == 3  /* UCC4 */
-	{	"/" OF_QE "/ucc@3200/mac-address",
+	{	"/" OF_QE "/ucc@3200",
 		"mac-address",
 		fdt_set_eth1
 	},
-	{	"/" OF_QE "/ucc@3200/mac-address",
+	{	"/" OF_QE "/ucc@3200",
 		"local-mac-address",
 		fdt_set_eth1
 	},
 #endif
-#endif
+#endif /* CONFIG_UEC_ETH2 */
 };
 
 void
@@ -487,20 +502,23 @@ ft_cpu_setup(void *blob, bd_t *bd)
 	int  j;
 
 	for (j = 0; j < (sizeof(fixup_props) / sizeof(fixup_props[0])); j++) {
-		nodeoffset = fdt_path_offset(fdt, fixup_props[j].node);
+		nodeoffset = fdt_find_node_by_path(blob, fixup_props[j].node);
 		if (nodeoffset >= 0) {
-			err = (*fixup_props[j].set_fn)(blob, nodeoffset, fixup_props[j].prop, bd);
+			err = fixup_props[j].set_fn(blob, nodeoffset,
+						    fixup_props[j].prop, bd);
 			if (err < 0)
-				printf("set_fn/libfdt: %s %s returned %s\n",
+				debug("Problem setting %s = %s: %s\n",
 					fixup_props[j].node,
 					fixup_props[j].prop,
 					fdt_strerror(err));
+		} else {
+			debug("Couldn't find %s: %s\n",
+				fixup_props[j].node,
+				fdt_strerror(nodeoffset));
 		}
 	}
 }
-#endif
-
-#if defined(CONFIG_OF_FLAT_TREE)
+#elif defined(CONFIG_OF_FLAT_TREE)
 void
 ft_cpu_setup(void *blob, bd_t *bd)
 {
diff --git a/cpu/mpc83xx/cpu_init.c b/cpu/mpc83xx/cpu_init.c
index 3ac91619c4ba8cf4a20035d540b8fadbae6b8e46..722497966a105600d5f0233170231fb8d9d33909 100644
--- a/cpu/mpc83xx/cpu_init.c
+++ b/cpu/mpc83xx/cpu_init.c
@@ -83,20 +83,30 @@ void cpu_init_f (volatile immap_t * im)
 	im->sysconf.spcr = (im->sysconf.spcr & ~SPCR_TSEC2EP) | (CFG_SPCR_TSEC2EP << SPCR_TSEC2EP_SHIFT);
 #endif
 
-#ifdef CONFIG_MPC834X
 #ifdef CFG_SCCR_TSEC1CM
 	/* TSEC1 clock mode */
 	im->clk.sccr = (im->clk.sccr & ~SCCR_TSEC1CM) | (CFG_SCCR_TSEC1CM << SCCR_TSEC1CM_SHIFT);
 #endif
+
 #ifdef CFG_SCCR_TSEC2CM
 	/* TSEC2 & I2C1 clock mode */
 	im->clk.sccr = (im->clk.sccr & ~SCCR_TSEC2CM) | (CFG_SCCR_TSEC2CM << SCCR_TSEC2CM_SHIFT);
 #endif
+
+#ifdef CFG_SCCR_TSEC1ON
+	/* TSEC1 clock switch */
+	im->clk.sccr = (im->clk.sccr & ~SCCR_TSEC1ON) | (CFG_SCCR_TSEC1ON << SCCR_TSEC1ON_SHIFT);
+#endif
+
+#ifdef CFG_SCCR_TSEC2ON
+	/* TSEC2 clock switch */
+	im->clk.sccr = (im->clk.sccr & ~SCCR_TSEC2ON) | (CFG_SCCR_TSEC2ON << SCCR_TSEC2ON_SHIFT);
+#endif
+
 #ifdef CFG_SCCR_USBMPHCM
 	/* USB MPH clock mode */
 	im->clk.sccr = (im->clk.sccr & ~SCCR_USBMPHCM) | (CFG_SCCR_USBMPHCM << SCCR_USBMPHCM_SHIFT);
 #endif
-#endif /* CONFIG_MPC834X */
 
 #ifdef CFG_SCCR_PCICM
 	/* PCI & DMA clock mode */
@@ -247,3 +257,39 @@ int cpu_init_r (void)
 #endif
 	return 0;
 }
+
+/*
+ * Figure out the cause of the reset
+ */
+int prt_83xx_rsr(void)
+{
+	static struct {
+		ulong mask;
+		char *desc;
+	} bits[] = {
+		{
+		RSR_SWSR, "Software Soft"}, {
+		RSR_SWHR, "Software Hard"}, {
+		RSR_JSRS, "JTAG Soft"}, {
+		RSR_CSHR, "Check Stop"}, {
+		RSR_SWRS, "Software Watchdog"}, {
+		RSR_BMRS, "Bus Monitor"}, {
+		RSR_SRS,  "External/Internal Soft"}, {
+		RSR_HRS,  "External/Internal Hard"}
+	};
+	static int n = sizeof bits / sizeof bits[0];
+	ulong rsr = gd->reset_status;
+	int i;
+	char *sep;
+
+	puts("Reset Status:");
+
+	sep = " ";
+	for (i = 0; i < n; i++)
+		if (rsr & bits[i].mask) {
+			printf("%s%s", sep, bits[i].desc);
+			sep = ", ";
+		}
+	puts("\n\n");
+	return 0;
+}
diff --git a/cpu/mpc83xx/ecc.c b/cpu/mpc83xx/ecc.c
new file mode 100644
index 0000000000000000000000000000000000000000..6f13094243a1cacaadb6a531c9d0a141abee76a2
--- /dev/null
+++ b/cpu/mpc83xx/ecc.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2007 Freescale Semiconductor, Inc.
+ *
+ * Dave Liu <daveliu@freescale.com>
+ * based on the contribution of Marian Balakowicz <m8@semihalf.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <common.h>
+#include <mpc83xx.h>
+#include <command.h>
+
+#if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD)
+void ecc_print_status(void)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile ddr83xx_t *ddr = &immap->ddr;
+
+	printf("\nECC mode: %s\n\n",
+	       (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF");
+
+	/* Interrupts */
+	printf("Memory Error Interrupt Enable:\n");
+	printf("  Multiple-Bit Error Interrupt Enable: %d\n",
+	       (ddr->err_int_en & ECC_ERR_INT_EN_MBEE) ? 1 : 0);
+	printf("  Single-Bit Error Interrupt Enable: %d\n",
+	       (ddr->err_int_en & ECC_ERR_INT_EN_SBEE) ? 1 : 0);
+	printf("  Memory Select Error Interrupt Enable: %d\n\n",
+	       (ddr->err_int_en & ECC_ERR_INT_EN_MSEE) ? 1 : 0);
+
+	/* Error disable */
+	printf("Memory Error Disable:\n");
+	printf("  Multiple-Bit Error Disable: %d\n",
+	       (ddr->err_disable & ECC_ERROR_DISABLE_MBED) ? 1 : 0);
+	printf("  Sinle-Bit Error Disable: %d\n",
+	       (ddr->err_disable & ECC_ERROR_DISABLE_SBED) ? 1 : 0);
+	printf("  Memory Select Error Disable: %d\n\n",
+	       (ddr->err_disable & ECC_ERROR_DISABLE_MSED) ? 1 : 0);
+
+	/* Error injection */
+	printf("Memory Data Path Error Injection Mask High/Low: %08lx %08lx\n",
+	       ddr->data_err_inject_hi, ddr->data_err_inject_lo);
+
+	printf("Memory Data Path Error Injection Mask ECC:\n");
+	printf("  ECC Mirror Byte: %d\n",
+	       (ddr->ecc_err_inject & ECC_ERR_INJECT_EMB) ? 1 : 0);
+	printf("  ECC Injection Enable: %d\n",
+	       (ddr->ecc_err_inject & ECC_ERR_INJECT_EIEN) ? 1 : 0);
+	printf("  ECC Error Injection Mask: 0x%02x\n\n",
+	       ddr->ecc_err_inject & ECC_ERR_INJECT_EEIM);
+
+	/* SBE counter/threshold */
+	printf("Memory Single-Bit Error Management (0..255):\n");
+	printf("  Single-Bit Error Threshold: %d\n",
+	       (ddr->err_sbe & ECC_ERROR_MAN_SBET) >> ECC_ERROR_MAN_SBET_SHIFT);
+	printf("  Single-Bit Error Counter: %d\n\n",
+	       (ddr->err_sbe & ECC_ERROR_MAN_SBEC) >> ECC_ERROR_MAN_SBEC_SHIFT);
+
+	/* Error detect */
+	printf("Memory Error Detect:\n");
+	printf("  Multiple Memory Errors: %d\n",
+	       (ddr->err_detect & ECC_ERROR_DETECT_MME) ? 1 : 0);
+	printf("  Multiple-Bit Error: %d\n",
+	       (ddr->err_detect & ECC_ERROR_DETECT_MBE) ? 1 : 0);
+	printf("  Single-Bit Error: %d\n",
+	       (ddr->err_detect & ECC_ERROR_DETECT_SBE) ? 1 : 0);
+	printf("  Memory Select Error: %d\n\n",
+	       (ddr->err_detect & ECC_ERROR_DETECT_MSE) ? 1 : 0);
+
+	/* Capture data */
+	printf("Memory Error Address Capture: 0x%08lx\n", ddr->capture_address);
+	printf("Memory Data Path Read Capture High/Low: %08lx %08lx\n",
+	       ddr->capture_data_hi, ddr->capture_data_lo);
+	printf("Memory Data Path Read Capture ECC: 0x%02x\n\n",
+	       ddr->capture_ecc & CAPTURE_ECC_ECE);
+
+	printf("Memory Error Attributes Capture:\n");
+	printf(" Data Beat Number: %d\n",
+	       (ddr->capture_attributes & ECC_CAPT_ATTR_BNUM) >>
+	       ECC_CAPT_ATTR_BNUM_SHIFT);
+	printf("  Transaction Size: %d\n",
+	       (ddr->capture_attributes & ECC_CAPT_ATTR_TSIZ) >>
+	       ECC_CAPT_ATTR_TSIZ_SHIFT);
+	printf("  Transaction Source: %d\n",
+	       (ddr->capture_attributes & ECC_CAPT_ATTR_TSRC) >>
+	       ECC_CAPT_ATTR_TSRC_SHIFT);
+	printf("  Transaction Type: %d\n",
+	       (ddr->capture_attributes & ECC_CAPT_ATTR_TTYP) >>
+	       ECC_CAPT_ATTR_TTYP_SHIFT);
+	printf("  Error Information Valid: %d\n\n",
+	       ddr->capture_attributes & ECC_CAPT_ATTR_VLD);
+}
+
+int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile ddr83xx_t *ddr = &immap->ddr;
+	volatile u32 val;
+	u64 *addr;
+	u32 count;
+	register u64 *i;
+	u32 ret[2];
+	u32 pattern[2];
+	u32 writeback[2];
+
+	/* The pattern is written into memory to generate error */
+	pattern[0] = 0xfedcba98UL;
+	pattern[1] = 0x76543210UL;
+
+	/* After injecting error, re-initialize the memory with the value */
+	writeback[0] = 0x01234567UL;
+	writeback[1] = 0x89abcdefUL;
+
+	if (argc > 4) {
+		printf("Usage:\n%s\n", cmdtp->usage);
+		return 1;
+	}
+
+	if (argc == 2) {
+		if (strcmp(argv[1], "status") == 0) {
+			ecc_print_status();
+			return 0;
+		} else if (strcmp(argv[1], "captureclear") == 0) {
+			ddr->capture_address = 0;
+			ddr->capture_data_hi = 0;
+			ddr->capture_data_lo = 0;
+			ddr->capture_ecc = 0;
+			ddr->capture_attributes = 0;
+			return 0;
+		}
+	}
+	if (argc == 3) {
+		if (strcmp(argv[1], "sbecnt") == 0) {
+			val = simple_strtoul(argv[2], NULL, 10);
+			if (val > 255) {
+				printf("Incorrect Counter value, "
+				       "should be 0..255\n");
+				return 1;
+			}
+
+			val = (val << ECC_ERROR_MAN_SBEC_SHIFT);
+			val |= (ddr->err_sbe & ECC_ERROR_MAN_SBET);
+
+			ddr->err_sbe = val;
+			return 0;
+		} else if (strcmp(argv[1], "sbethr") == 0) {
+			val = simple_strtoul(argv[2], NULL, 10);
+			if (val > 255) {
+				printf("Incorrect Counter value, "
+				       "should be 0..255\n");
+				return 1;
+			}
+
+			val = (val << ECC_ERROR_MAN_SBET_SHIFT);
+			val |= (ddr->err_sbe & ECC_ERROR_MAN_SBEC);
+
+			ddr->err_sbe = val;
+			return 0;
+		} else if (strcmp(argv[1], "errdisable") == 0) {
+			val = ddr->err_disable;
+
+			if (strcmp(argv[2], "+sbe") == 0) {
+				val |= ECC_ERROR_DISABLE_SBED;
+			} else if (strcmp(argv[2], "+mbe") == 0) {
+				val |= ECC_ERROR_DISABLE_MBED;
+			} else if (strcmp(argv[2], "+mse") == 0) {
+				val |= ECC_ERROR_DISABLE_MSED;
+			} else if (strcmp(argv[2], "+all") == 0) {
+				val |= (ECC_ERROR_DISABLE_SBED |
+					ECC_ERROR_DISABLE_MBED |
+					ECC_ERROR_DISABLE_MSED);
+			} else if (strcmp(argv[2], "-sbe") == 0) {
+				val &= ~ECC_ERROR_DISABLE_SBED;
+			} else if (strcmp(argv[2], "-mbe") == 0) {
+				val &= ~ECC_ERROR_DISABLE_MBED;
+			} else if (strcmp(argv[2], "-mse") == 0) {
+				val &= ~ECC_ERROR_DISABLE_MSED;
+			} else if (strcmp(argv[2], "-all") == 0) {
+				val &= ~(ECC_ERROR_DISABLE_SBED |
+					 ECC_ERROR_DISABLE_MBED |
+					 ECC_ERROR_DISABLE_MSED);
+			} else {
+				printf("Incorrect err_disable field\n");
+				return 1;
+			}
+
+			ddr->err_disable = val;
+			__asm__ __volatile__("sync");
+			__asm__ __volatile__("isync");
+			return 0;
+		} else if (strcmp(argv[1], "errdetectclr") == 0) {
+			val = ddr->err_detect;
+
+			if (strcmp(argv[2], "mme") == 0) {
+				val |= ECC_ERROR_DETECT_MME;
+			} else if (strcmp(argv[2], "sbe") == 0) {
+				val |= ECC_ERROR_DETECT_SBE;
+			} else if (strcmp(argv[2], "mbe") == 0) {
+				val |= ECC_ERROR_DETECT_MBE;
+			} else if (strcmp(argv[2], "mse") == 0) {
+				val |= ECC_ERROR_DETECT_MSE;
+			} else if (strcmp(argv[2], "all") == 0) {
+				val |= (ECC_ERROR_DETECT_MME |
+					ECC_ERROR_DETECT_MBE |
+					ECC_ERROR_DETECT_SBE |
+					ECC_ERROR_DETECT_MSE);
+			} else {
+				printf("Incorrect err_detect field\n");
+				return 1;
+			}
+
+			ddr->err_detect = val;
+			return 0;
+		} else if (strcmp(argv[1], "injectdatahi") == 0) {
+			val = simple_strtoul(argv[2], NULL, 16);
+
+			ddr->data_err_inject_hi = val;
+			return 0;
+		} else if (strcmp(argv[1], "injectdatalo") == 0) {
+			val = simple_strtoul(argv[2], NULL, 16);
+
+			ddr->data_err_inject_lo = val;
+			return 0;
+		} else if (strcmp(argv[1], "injectecc") == 0) {
+			val = simple_strtoul(argv[2], NULL, 16);
+			if (val > 0xff) {
+				printf("Incorrect ECC inject mask, "
+				       "should be 0x00..0xff\n");
+				return 1;
+			}
+			val |= (ddr->ecc_err_inject & ~ECC_ERR_INJECT_EEIM);
+
+			ddr->ecc_err_inject = val;
+			return 0;
+		} else if (strcmp(argv[1], "inject") == 0) {
+			val = ddr->ecc_err_inject;
+
+			if (strcmp(argv[2], "en") == 0)
+				val |= ECC_ERR_INJECT_EIEN;
+			else if (strcmp(argv[2], "dis") == 0)
+				val &= ~ECC_ERR_INJECT_EIEN;
+			else
+				printf("Incorrect command\n");
+
+			ddr->ecc_err_inject = val;
+			__asm__ __volatile__("sync");
+			__asm__ __volatile__("isync");
+			return 0;
+		} else if (strcmp(argv[1], "mirror") == 0) {
+			val = ddr->ecc_err_inject;
+
+			if (strcmp(argv[2], "en") == 0)
+				val |= ECC_ERR_INJECT_EMB;
+			else if (strcmp(argv[2], "dis") == 0)
+				val &= ~ECC_ERR_INJECT_EMB;
+			else
+				printf("Incorrect command\n");
+
+			ddr->ecc_err_inject = val;
+			return 0;
+		}
+	}
+	if (argc == 4) {
+		if (strcmp(argv[1], "testdw") == 0) {
+			addr = (u64 *) simple_strtoul(argv[2], NULL, 16);
+			count = simple_strtoul(argv[3], NULL, 16);
+
+			if ((u32) addr % 8) {
+				printf("Address not alligned on "
+				       "double word boundary\n");
+				return 1;
+			}
+			disable_interrupts();
+
+			for (i = addr; i < addr + count; i++) {
+
+				/* enable injects */
+				ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
+				__asm__ __volatile__("sync");
+				__asm__ __volatile__("isync");
+
+				/* write memory location injecting errors */
+				ppcDWstore((u32 *) i, pattern);
+				__asm__ __volatile__("sync");
+
+				/* disable injects */
+				ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
+				__asm__ __volatile__("sync");
+				__asm__ __volatile__("isync");
+
+				/* read data, this generates ECC error */
+				ppcDWload((u32 *) i, ret);
+				__asm__ __volatile__("sync");
+
+				/* re-initialize memory, double word write the location again,
+				 * generates new ECC code this time */
+				ppcDWstore((u32 *) i, writeback);
+				__asm__ __volatile__("sync");
+			}
+			enable_interrupts();
+			return 0;
+		}
+		if (strcmp(argv[1], "testword") == 0) {
+			addr = (u64 *) simple_strtoul(argv[2], NULL, 16);
+			count = simple_strtoul(argv[3], NULL, 16);
+
+			if ((u32) addr % 8) {
+				printf("Address not alligned on "
+				       "double word boundary\n");
+				return 1;
+			}
+			disable_interrupts();
+
+			for (i = addr; i < addr + count; i++) {
+
+				/* enable injects */
+				ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
+				__asm__ __volatile__("sync");
+				__asm__ __volatile__("isync");
+
+				/* write memory location injecting errors */
+				*(u32 *) i = 0xfedcba98UL;
+				__asm__ __volatile__("sync");
+
+				/* sub double word write,
+				 * bus will read-modify-write,
+				 * generates ECC error */
+				*((u32 *) i + 1) = 0x76543210UL;
+				__asm__ __volatile__("sync");
+
+				/* disable injects */
+				ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
+				__asm__ __volatile__("sync");
+				__asm__ __volatile__("isync");
+
+				/* re-initialize memory,
+				 * double word write the location again,
+				 * generates new ECC code this time */
+				ppcDWstore((u32 *) i, writeback);
+				__asm__ __volatile__("sync");
+			}
+			enable_interrupts();
+			return 0;
+		}
+	}
+	printf("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+}
+
+U_BOOT_CMD(ecc, 4, 0, do_ecc,
+	   "ecc     - support for DDR ECC features\n",
+	   "status              - print out status info\n"
+	   "ecc captureclear        - clear capture regs data\n"
+	   "ecc sbecnt <val>        - set Single-Bit Error counter\n"
+	   "ecc sbethr <val>        - set Single-Bit Threshold\n"
+	   "ecc errdisable <flag>   - clear/set disable Memory Error Disable, flag:\n"
+	   "  [-|+]sbe - Single-Bit Error\n"
+	   "  [-|+]mbe - Multiple-Bit Error\n"
+	   "  [-|+]mse - Memory Select Error\n"
+	   "  [-|+]all - all errors\n"
+	   "ecc errdetectclr <flag> - clear Memory Error Detect, flag:\n"
+	   "  mme - Multiple Memory Errors\n"
+	   "  sbe - Single-Bit Error\n"
+	   "  mbe - Multiple-Bit Error\n"
+	   "  mse - Memory Select Error\n"
+	   "  all - all errors\n"
+	   "ecc injectdatahi <hi>  - set Memory Data Path Error Injection Mask High\n"
+	   "ecc injectdatalo <lo>  - set Memory Data Path Error Injection Mask Low\n"
+	   "ecc injectecc <ecc>    - set ECC Error Injection Mask\n"
+	   "ecc inject <en|dis>    - enable/disable error injection\n"
+	   "ecc mirror <en|dis>    - enable/disable mirror byte\n"
+	   "ecc testdw <addr> <cnt>  - test mem region with double word access:\n"
+	   "  - enables injects\n"
+	   "  - writes pattern injecting errors with double word access\n"
+	   "  - disables injects\n"
+	   "  - reads pattern back with double word access, generates error\n"
+	   "  - re-inits memory\n"
+	   "ecc testword <addr> <cnt>  - test mem region with word access:\n"
+	   "  - enables injects\n"
+	   "  - writes pattern injecting errors with word access\n"
+	   "  - writes pattern with word access, generates error\n"
+	   "  - disables injects\n" "  - re-inits memory");
+#endif
diff --git a/cpu/mpc83xx/pci.c b/cpu/mpc83xx/pci.c
index 785d6129daf76e24ae3bf48c27757551b70f1092..229821887082c46e11806b114f0984ca48408635 100644
--- a/cpu/mpc83xx/pci.c
+++ b/cpu/mpc83xx/pci.c
@@ -25,7 +25,14 @@
 
 #include <common.h>
 #include <pci.h>
+
+#if defined(CONFIG_OF_LIBFDT)
+#include <libfdt.h>
+#include <libfdt_env.h>
+#elif defined(CONFIG_OF_FLAT_TREE)
 #include <ft_build.h>
+#endif
+
 #include <asm/mpc8349_pci.h>
 
 #ifdef CONFIG_83XX_GENERIC_PCI
@@ -163,7 +170,34 @@ void mpc83xx_pci_init(int num_buses, struct pci_region **reg, int warmboot)
 		pci_init_bus(i, reg[i]);
 }
 
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_LIBFDT)
+void ft_pci_setup(void *blob, bd_t *bd)
+{
+	int nodeoffset;
+	int err;
+	int tmp[2];
+
+	if (pci_num_buses < 1)
+		return;
+
+	nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8500");
+	if (nodeoffset >= 0) {
+		tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
+		tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
+		err = fdt_setprop(blob, nodeoffset, "bus-range", tmp, sizeof(tmp));
+	}
+
+	if (pci_num_buses < 2)
+		return;
+
+	nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8600");
+	if (nodeoffset >= 0) {
+		tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
+		tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
+		err = fdt_setprop(blob, nodeoffset, "bus-range", tmp, sizeof(tmp));
+	}
+}
+#elif CONFIG_OF_FLAT_TREE
 void ft_pci_setup(void *blob, bd_t *bd)
 {
 	u32 *p;
diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c
index 647813f68d94e5ae020e60d5e749adbebe972f5b..54f0c83d454013cb7564f7acd87fe6ce518b9afe 100644
--- a/cpu/mpc83xx/spd_sdram.c
+++ b/cpu/mpc83xx/spd_sdram.c
@@ -574,7 +574,10 @@ long int spd_sdram()
 
 	/* Check DIMM data bus width */
 	if (spd.dataw_lsb == 0x20) {
-		burstlen = 0x03; /* 32 bit data bus, burst len is 8 */
+		if (spd.mem_type == SPD_MEMTYPE_DDR)
+			burstlen = 0x03; /* 32 bit data bus, burst len is 8 */
+		else
+			burstlen = 0x02; /* 32 bit data bus, burst len is 4 */
 		printf("\n   DDR DIMM: data bus width is 32 bit");
 	} else {
 		burstlen = 0x02; /* Others act as 64 bit bus, burst len is 4 */
@@ -730,8 +733,12 @@ long int spd_sdram()
 		sdram_cfg |= 0x10000000;
 
 	/* The DIMM is 32bit width */
-	if (spd.dataw_lsb == 0x20)
-		sdram_cfg |= 0x000C0000;
+	if (spd.dataw_lsb == 0x20) {
+		if (spd.mem_type == SPD_MEMTYPE_DDR)
+			sdram_cfg |= 0x000C0000;
+		if (spd.mem_type == SPD_MEMTYPE_DDR2)
+			sdram_cfg |= 0x00080000;
+	}
 
 	ddrc_ecc_enable = 0;
 
diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
index 4068b53208f9842d3307d88039698cfbda4231bc..af9da5b95fde6ab1dfddc5c51c62a2061cfb1968 100644
--- a/cpu/ppc4xx/Makefile
+++ b/cpu/ppc4xx/Makefile
@@ -27,12 +27,12 @@ LIB	= $(obj)lib$(CPU).a
 
 START	= start.o resetvec.o kgdb.o
 SOBJS	= dcr.o
-COBJS	= 405gp_pci.o 4xx_enet.o \
+COBJS	= 405gp_pci.o 440spe_pcie.o 4xx_enet.o \
 	  bedbug_405.o commproc.o \
 	  cpu.o cpu_init.o gpio.o i2c.o interrupts.o \
 	  miiphy.o ndfc.o sdram.o serial.o \
 	  40x_spd_sdram.o 44x_spd_ddr.o 44x_spd_ddr2.o speed.o \
-	  tlb.o traps.o usb_ohci.o usbdev.o \
+	  tlb.o traps.o usb_ohci.o usb.o usbdev.o \
 	  440spe_pcie.o
 
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/cpu/ppc4xx/usb.c b/cpu/ppc4xx/usb.c
new file mode 100644
index 0000000000000000000000000000000000000000..2837b37c58e530f6e6002ba5915970d0deaeaf54
--- /dev/null
+++ b/cpu/ppc4xx/usb.c
@@ -0,0 +1,50 @@
+/*
+ * (C) Copyright 2007
+ * Markus Klotzbuecher, DENX Software Engineering <mk@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <common.h>
+
+#if defined(CONFIG_USB_OHCI_NEW) && defined(CFG_USB_OHCI_CPU_INIT)
+
+#include "usbdev.h"
+
+int usb_cpu_init()
+{
+
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPX)
+	usb_dev_init();
+#endif
+
+	return 0;
+}
+
+int usb_cpu_stop()
+{
+	return 0;
+}
+
+int usb_cpu_init_fail()
+{
+	return 0;
+}
+
+#endif /* defined(CONFIG_USB_OHCI) && defined(CFG_USB_OHCI_CPU_INIT) */
diff --git a/cpu/pxa/Makefile b/cpu/pxa/Makefile
index cded7ffd35d497d700af0b2a954024798860862f..8b4367e20510c38e477525a15809a6abb81e23ed 100644
--- a/cpu/pxa/Makefile
+++ b/cpu/pxa/Makefile
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-COBJS	= serial.o interrupts.o cpu.o i2c.o pxafb.o mmc.o
+COBJS	= serial.o interrupts.o cpu.o i2c.o pxafb.o mmc.o usb.o
 
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/pxa/usb.c b/cpu/pxa/usb.c
new file mode 100644
index 0000000000000000000000000000000000000000..65f457fe59d5240e4297d3785763e79eeca2142f
--- /dev/null
+++ b/cpu/pxa/usb.c
@@ -0,0 +1,79 @@
+/*
+ * (C) Copyright 2006
+ * Markus Klotzbuecher, DENX Software Engineering <mk@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <common.h>
+
+#if defined(CONFIG_USB_OHCI_NEW) && defined(CFG_USB_OHCI_CPU_INIT)
+# if defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_PXA27X)
+
+#include <asm/arch/pxa-regs.h>
+
+int usb_cpu_init()
+{
+#if defined(CONFIG_CPU_MONAHANS)
+	/* Enable USB host clock. */
+	CKENA |= (CKENA_2_USBHOST |  CKENA_20_UDC);
+	udelay(100);
+#endif
+#if defined(CONFIG_PXA27X)
+	/* Enable USB host clock. */
+	CKEN |= CKEN10_USBHOST;
+#endif
+
+#if defined(CONFIG_CPU_MONAHANS)
+	/* Configure Port 2 for Host (USB Client Registers) */
+	UP2OCR = 0x3000c;
+#endif
+
+	UHCHR |= UHCHR_FHR;
+	wait_ms(11);
+	UHCHR &= ~UHCHR_FHR;
+
+	UHCHR |= UHCHR_FSBIR;
+	while (UHCHR & UHCHR_FSBIR)
+		udelay(1);
+
+#if defined(CONFIG_CPU_MONAHANS)
+	UHCHR &= ~UHCHR_SSEP0;
+#endif
+#if defined(CONFIG_PXA27X)
+	UHCHR &= ~UHCHR_SSEP2;
+#endif
+	UHCHR &= ~UHCHR_SSEP1;
+	UHCHR &= ~UHCHR_SSE;
+
+	return 0;
+}
+
+int usb_cpu_stop()
+{
+	return 0;
+}
+
+int usb_cpu_init_fail()
+{
+	return 0;
+}
+
+# endif /* defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_PXA27X) */
+#endif /* defined(CONFIG_USB_OHCI) && defined(CFG_USB_OHCI_CPU_INIT) */
diff --git a/doc/README.generic_usb_ohci b/doc/README.generic_usb_ohci
new file mode 100644
index 0000000000000000000000000000000000000000..c343dfdf90af41c74b738e214703d03564361ae4
--- /dev/null
+++ b/doc/README.generic_usb_ohci
@@ -0,0 +1,60 @@
+Notes on the the generic USB-OHCI driver
+========================================
+
+This driver (drivers/usb_ohci.[ch]) is the result of the merge of
+various existing OHCI drivers that were basically identical beside
+cpu/board dependant initalization. This initalization has been moved
+into cpu/board directories and are called via the hooks below.
+
+Configuration options
+----------------------
+
+	CONFIG_USB_OHCI_NEW: enable the new OHCI driver
+
+	CFG_USB_OHCI_BOARD_INIT: call the board dependant hooks:
+
+		  - extern int usb_board_init(void);
+		  - extern int usb_board_stop(void);
+		  - extern int usb_cpu_init_fail(void);
+
+	CFG_USB_OHCI_CPU_INIT: call the cpu dependant hooks:
+
+		  - extern int usb_cpu_init(void);
+		  - extern int usb_cpu_stop(void);
+		  - extern int usb_cpu_init_fail(void);
+
+	CFG_USB_OHCI_REGS_BASE: defines the base address of the OHCI
+				registers
+
+	CFG_USB_OHCI_SLOT_NAME: slot name
+
+	CFG_USB_OHCI_MAX_ROOT_PORTS: maximal number of ports of the
+				     root hub.
+
+
+Endianness issues
+------------------
+
+The USB bus operates in little endian, but unfortunately there are
+OHCI controllers that operate in big endian such as ppc4xx and
+mpc5xxx. For these the config option
+
+	CFG_OHCI_BE_CONTROLLER
+
+needs to be defined. 
+
+
+PCI Controllers
+----------------
+
+You'll need to define
+
+	CONFIG_PCI_OHCI
+
+PCI Controllers need to do byte swapping on register accesses, so they
+should to define:
+
+	CFG_OHCI_SWAP_REG_ACCESS
+
+
+
diff --git a/doc/README.mpc8323erdb b/doc/README.mpc8323erdb
new file mode 100644
index 0000000000000000000000000000000000000000..6f89829373575f6167226fd29aeffe31fbd750f3
--- /dev/null
+++ b/doc/README.mpc8323erdb
@@ -0,0 +1,71 @@
+Freescale MPC8323ERDB Board
+-----------------------------------------
+
+1.	Memory Map
+	The memory map looks like this:
+
+	0x0000_0000	0x03ff_ffff	DDR		 64M
+	0x8000_0000	0x8fff_ffff	PCI MEM		 256M
+	0x9000_0000	0x9fff_ffff	PCI_MMIO	 256M
+	0xe000_0000	0xe00f_ffff	IMMR		 1M
+	0xd000_0000	0xd3ff_ffff	PCI IO		 64M
+	0xfe00_0000	0xfeff_ffff	NOR FLASH (CS0)	 16M
+
+2.	Compilation
+
+	Assuming you're using BASH (or similar) as your shell:
+
+	export CROSS_COMPILE=your-cross-compiler-prefix-
+	make distclean
+	make MPC8323ERDB_config
+	make
+
+3.	Downloading and Flashing Images
+
+3.1	Reflash U-boot Image using U-boot
+
+	N.b, have an alternate means of programming
+	the flash available if the new u-boot doesn't boot.
+
+	First try a:
+
+	tftpboot $loadaddr $uboot
+
+	to make sure that the TFTP load will succeed before
+	an erase goes ahead and wipes out your current firmware.
+	Then do a:
+
+	run tftpflash
+
+	which is a shorter version of the manual sequence:
+
+	tftp $loadaddr u-boot.bin
+	protect off fe000000 +$filesize
+	erase fe000000 +$filesize
+	cp.b $loadaddr fe000000 $filesize
+
+	To keep your old u-boot's environment variables, do a:
+
+	saveenv
+
+	prior to resetting the board.
+
+3.2	Downloading and Booting Linux Kernel
+
+	Ensure that all networking-related environment variables are set
+	properly (including ipaddr, serverip, gatewayip (if needed),
+	netmask, ethaddr, eth1addr, rootpath (if using NFS root),
+	fdtfile, and bootfile).
+
+	Then, do one of the following, depending on whether you
+	want an NFS root or a ramdisk root:
+
+	run nfsboot
+
+	or
+
+	run ramboot
+
+4	Notes
+
+	The console baudrate for MPC8323ERDB is 115200bps.
diff --git a/doc/README.mpc8360emds b/doc/README.mpc8360emds
index c87469f43d10db14e7c43c2b3d5fc1943352265e..5f202475b586b52c98bdd8f943213246af3451c0 100644
--- a/doc/README.mpc8360emds
+++ b/doc/README.mpc8360emds
@@ -21,7 +21,13 @@ Freescale MPC8360EMDS Board
 	SW3[1:8]= 0000_0001 refers to bits labeled 1 through 6 is set as "On"
 		and bits labeled 8 is set as "Off".
 
-1.1	For the MPC8360E PB PROTO Board
+1.1	There are three type boards for MPC8360E silicon up to now, They are
+
+	* MPC8360E-MDS-PB PROTO (a.k.a 8360SYS PROTOTYPE)
+	* MPC8360E-MDS-PB PILOT (a.k.a 8360SYS PILOT)
+	* MPC8360EA-MDS-PB PROTO (a.k.a 8360SYS2 PROTOTYPE)
+
+1.2	For all the MPC8360EMDS Board
 
 	First, make sure the board default setting is consistent with the
 	document shipped with your board. Then apply the following setting:
@@ -33,6 +39,21 @@ Freescale MPC8360EMDS Board
 	JP6 1-2
 	on board Oscillator: 66M
 
+1.3	Since different board/chip rev. combinations have AC timing issues,
+	u-boot forces RGMII-ID (RGMII with Internal Delay) mode on by default
+	by the patch (mpc83xx: Disable G1TXCLK, G2TXCLK h/w buffers).
+
+	When the rev2.x silicon mount on these boards, and if you are using
+	u-boot version after this patch, to make the ethernet interfaces usable,
+	and to enable RGMII-ID on your board, you have to setup the jumpers
+	correctly.
+
+	* MPC8360E-MDS-PB PROTO
+	  nothing to do
+	* MPC8360E-MDS-PB PILOT
+	  JP9 and JP8 should be ON
+	* MPC8360EA-MDS-PB PROTO
+	  JP2 and JP3 should be ON
 
 2.	Memory Map
 
diff --git a/doc/README.mpc8349emds.ddrecc b/doc/README.mpc83xx.ddrecc
similarity index 62%
rename from doc/README.mpc8349emds.ddrecc
rename to doc/README.mpc83xx.ddrecc
index eb249c3956f15a8dd810ceb2f592418761b166b4..0029f08759d611edead742d6323f8978ce62e792 100644
--- a/doc/README.mpc8349emds.ddrecc
+++ b/doc/README.mpc83xx.ddrecc
@@ -15,10 +15,10 @@ IMPORTANT NOTICE: enabling injecting multiple-bit errors is potentially
 dangerous as such errors are NOT corrected by the controller. Therefore caution
 should be taken when enabling the injection of multiple-bit errors: it is only
 safe when used on a carefully selected memory area and used under control of
-the 'ecc test' command (see example 'Injecting Multiple-Bit Errors' below). In
-particular, when you simply set the multiple-bit errors in inject mask and
-enable injection, U-Boot is very likely to hang quickly as the errors will be
-injected when it accesses its code, data etc.
+the 'ecc testdw' 'ecc testword' command (see example 'Injecting Multiple-Bit
+Errors' below). In particular, when you simply set the multiple-bit errors in
+inject mask and enable injection, U-Boot is very likely to hang quickly as the
+errors will be injected when it accesses its code, data etc.
 
 
 Use cases for DDR 'ecc' command:
@@ -40,7 +40,7 @@ Injecting Single-Bit Errors
 
 2. Run test over some memory region
 
-=> ecc test 200000 10
+=> ecc testdw 200000 10
 
 3. Check ECC status
 
@@ -61,57 +61,57 @@ Memory Error Detect:
 16 errors were generated, Single-Bit Error flag was not set as Single Bit Error
 Counter did not reach  Single-Bit Error Threshold.
 
-4. Make sure used memory region got re-initialized with 0xcafecafe pattern
+4. Make sure used memory region got re-initialized with 0x0123456789abcdef
 
 => md 200000
-00200000: cafecafe cafecafe cafecafe cafecafe    ................
-00200010: cafecafe cafecafe cafecafe cafecafe    ................
-00200020: cafecafe cafecafe cafecafe cafecafe    ................
-00200030: cafecafe cafecafe cafecafe cafecafe    ................
-00200040: cafecafe cafecafe cafecafe cafecafe    ................
-00200050: cafecafe cafecafe cafecafe cafecafe    ................
-00200060: cafecafe cafecafe cafecafe cafecafe    ................
-00200070: cafecafe cafecafe cafecafe cafecafe    ................
+00200000: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200010: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200020: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200030: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200040: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200050: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200060: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200070: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
 00200080: deadbeef deadbeef deadbeef deadbeef    ................
 00200090: deadbeef deadbeef deadbeef deadbeef    ................
 
-
 Injecting Multiple-Bit Errors
 -----------------------------
 
 1. Set more than 1 bit in Data Path Error Inject Mask
 
-=> ecc injectdatahi 5
+=> ecc injectdatahi 1
+=> ecc injectdatalo 1
 
 2. Run test over some memory region
 
-=> ecc test 200000 10
+=> ecc testword 200000 1
 
 3. Check ECC status
 
 => ecc status
 ...
-Memory Data Path Error Injection Mask High/Low: 00000005 00000000
+Memory Data Path Error Injection Mask High/Low: 00000001 00000001
 ...
 Memory Error Detect:
-  Multiple Memory Errors: 1
+  Multiple Memory Errors: 0
   Multiple-Bit Error: 1
   Single-Bit Error: 0
 ...
 
-Observe that both Multiple Memory Errors and Multiple-Bit Error flags are set.
+The Multiple Memory Errors flags not set and Multiple-Bit Error flags are set.
 
-4. Make sure used memory region got re-initialized with 0xcafecafe pattern
+4. Make sure used memory region got re-initialized with 0x0123456789abcdef
 
 => md 200000
-00200000: cafecafe cafecafe cafecafe cafecafe    ................
-00200010: cafecafe cafecafe cafecafe cafecafe    ................
-00200020: cafecafe cafecafe cafecafe cafecafe    ................
-00200030: cafecafe cafecafe cafecafe cafecafe    ................
-00200040: cafecafe cafecafe cafecafe cafecafe    ................
-00200050: cafecafe cafecafe cafecafe cafecafe    ................
-00200060: cafecafe cafecafe cafecafe cafecafe    ................
-00200070: cafecafe cafecafe cafecafe cafecafe    ................
+00200000: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200010: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200020: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200030: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200040: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200050: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200060: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
+00200070: 01234567 89abcdef 01234567 89abcdef    .#Eg.....#Eg....
 00200080: deadbeef deadbeef deadbeef deadbeef    ................
 00200090: deadbeef deadbeef deadbeef deadbeef    ................
 
@@ -140,7 +140,7 @@ Test Single-Bit Error Counter and Threshold
 ...
 Memory Single-Bit Error Management (0..255):
   Single-Bit Error Threshold: 255
-  Single Bit Error Counter: 60
+  Single Bit Error Counter: 199
 
 Memory Error Detect:
   Multiple Memory Errors: 1
diff --git a/drivers/Makefile b/drivers/Makefile
index 881153ac9dd48e42c9b94428cfbee0a752cb6d0e..fc9804076233e07c5157c9a267148b8fddc4124a 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -31,7 +31,7 @@ COBJS	= 3c589.o 5701rls.o ali512x.o ata_piix.o atmel_usart.o \
 	  bcm570x.o bcm570x_autoneg.o cfb_console.o cfi_flash.o \
 	  cs8900.o ct69000.o dataflash.o dc2114x.o dm9000x.o \
 	  e1000.o eepro100.o enc28j60.o \
-	  i8042.o inca-ip_sw.o keyboard.o \
+	  i8042.o inca-ip_sw.o isp116x-hcd.o keyboard.o \
 	  lan91c96.o macb.o \
 	  natsemi.o ne2000.o netarm_eth.o netconsole.o \
 	  ns16550.o ns8382x.o ns87308.o ns7520_eth.o omap1510_i2c.o \
@@ -47,7 +47,9 @@ COBJS	= 3c589.o 5701rls.o ali512x.o ata_piix.o atmel_usart.o \
 	  status_led.o sym53c8xx.o systemace.o ahci.o \
 	  ti_pci1410a.o tigon3.o tsec.o \
 	  tsi108_eth.o tsi108_i2c.o tsi108_pci.o \
-	  usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \
+	  usb_ohci.o \
+	  usbdcore.o usbdcore_ep0.o usbdcore_mpc8xx.o usbdcore_omap1510.o \
+	  usbtty.o \
 	  videomodes.o w83c553f.o \
 	  ks8695eth.o \
 	  pxa_pcmcia.o mpc8xx_pcmcia.o tqm8xx_pcmcia.o	\
diff --git a/drivers/bios_emulator/Makefile b/drivers/bios_emulator/Makefile
index ba7d43673f718ed7a440a7c345f797abca7e0675..586e83be8f2abec30cb0d0cb41a1d1c5dbf86635 100644
--- a/drivers/bios_emulator/Makefile
+++ b/drivers/bios_emulator/Makefile
@@ -1,6 +1,6 @@
 include $(TOPDIR)/config.mk
 
-LIB := libatibiosemu.a
+LIB := $(obj)libatibiosemu.a
 
 X86DIR  = ./x86emu
 
diff --git a/drivers/fsl_i2c.c b/drivers/fsl_i2c.c
index ebae5af154ee95bcadd738e8a78a57372f66d7c7..22485ea916f4a958d31892192c277a48e29a05ae 100644
--- a/drivers/fsl_i2c.c
+++ b/drivers/fsl_i2c.c
@@ -69,9 +69,10 @@ i2c_init(int speed, int slaveadd)
 	dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET);
 
 	writeb(0, &dev->cr);			/* stop I2C controller */
+	udelay(5);				/* let it shutdown in peace */
 	writeb(0x3F, &dev->fdr);		/* set bus speed */
 	writeb(0x3F, &dev->dfsrr);		/* set default filter */
-	writeb(slaveadd, &dev->adr);		/* write slave address */
+	writeb(slaveadd << 1, &dev->adr);	/* write slave address */
 	writeb(0x0, &dev->sr);			/* clear status register */
 	writeb(I2C_CR_MEN, &dev->cr);		/* start I2C controller */
 #endif	/* CFG_I2C2_OFFSET */
diff --git a/drivers/isp116x-hcd.c b/drivers/isp116x-hcd.c
new file mode 100644
index 0000000000000000000000000000000000000000..8e2bc7adcc9814b4516a03325908ae3c265f0bd6
--- /dev/null
+++ b/drivers/isp116x-hcd.c
@@ -0,0 +1,1413 @@
+/*
+ * ISP116x HCD (Host Controller Driver) for u-boot.
+ *
+ * Copyright (C) 2006-2007 Rodolfo Giometti <giometti@linux.it>
+ * Copyright (C) 2006-2007 Eurotech S.p.A. <info@eurotech.it>
+ *
+ * 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
+ *
+ *
+ * Derived in part from the SL811 HCD driver "u-boot/drivers/sl811_usb.c"
+ * (original copyright message follows):
+ *
+ *    (C) Copyright 2004
+ *    Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ *    This code is based on linux driver for sl811hs chip, source at
+ *    drivers/usb/host/sl811.c:
+ *
+ *    SL811 Host Controller Interface driver for USB.
+ *
+ *    Copyright (c) 2003/06, Courage Co., Ltd.
+ *
+ *    Based on:
+ *         1.uhci.c by Linus Torvalds, Johannes Erdfelt, Randy Dunlap,
+ *           Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber,
+ *           Adam Richter, Gregory P. Smith;
+ *         2.Original SL811 driver (hc_sl811.o) by Pei Liu <pbl@cypress.com>
+ *         3.Rewrited as sl811.o by Yin Aihua <yinah:couragetech.com.cn>
+ *
+ *    [[GNU/GPL disclaimer]]
+ *
+ * and in part from AU1x00 OHCI HCD driver "u-boot/cpu/mips/au1x00_usb_ohci.c"
+ * (original copyright message follows):
+ *
+ *    URB OHCI HCD (Host Controller Driver) for USB on the AU1x00.
+ *
+ *    (C) Copyright 2003
+ *    Gary Jennejohn, DENX Software Engineering <gj@denx.de>
+ *
+ *    [[GNU/GPL disclaimer]]
+ *
+ *    Note: Part of this code has been derived from linux
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_USB_ISP116X_HCD
+#include <asm/io.h>
+#include <usb.h>
+#include <malloc.h>
+#include <linux/list.h>
+
+/*
+ * ISP116x chips require certain delays between accesses to its
+ * registers. The following timing options exist.
+ *
+ * 1. Configure your memory controller (the best)
+ * 2. Use ndelay (easiest, poorest). For that, enable the following macro.
+ *
+ * Value is in microseconds.
+ */
+#ifdef ISP116X_HCD_USE_UDELAY
+#define UDELAY		1
+#endif
+
+/*
+ * On some (slowly?) machines an extra delay after data packing into
+ * controller's FIFOs is required, * otherwise you may get the following
+ * error:
+ *
+ *   uboot> usb start
+ *   (Re)start USB...
+ *   USB:   scanning bus for devices... isp116x: isp116x_submit_job: CTL:TIMEOUT
+ *   isp116x: isp116x_submit_job: ****** FIFO not ready! ******
+ *
+ *         USB device not responding, giving up (status=4)
+ *         isp116x: isp116x_submit_job: ****** FIFO not empty! ******
+ *         isp116x: isp116x_submit_job: ****** FIFO not empty! ******
+ *         isp116x: isp116x_submit_job: ****** FIFO not empty! ******
+ *         3 USB Device(s) found
+ *                scanning bus for storage devices... 0 Storage Device(s) found
+ *
+ * Value is in milliseconds.
+ */
+#ifdef ISP116X_HCD_USE_EXTRA_DELAY
+#define EXTRA_DELAY	2
+#endif
+
+/*
+ * Enable the following defines if you wish enable debugging messages.
+ */
+#undef DEBUG			/* enable debugging messages */
+#undef TRACE			/* enable tracing code */
+#undef VERBOSE			/* verbose debugging messages */
+
+#include "isp116x.h"
+
+#define DRIVER_VERSION	"08 Jan 2007"
+static const char hcd_name[] = "isp116x-hcd";
+
+struct isp116x isp116x_dev;
+struct isp116x_platform_data isp116x_board;
+int got_rhsc = 0;		/* root hub status change */
+struct usb_device *devgone;	/* device which was disconnected */
+int rh_devnum = 0;		/* address of Root Hub endpoint */
+
+/* ------------------------------------------------------------------------- */
+
+#define ALIGN(x,a)	(((x)+(a)-1UL)&~((a)-1UL))
+#define min_t(type,x,y)	\
+	({ type __x = (x); type __y = (y); __x < __y ? __x : __y; })
+
+/* ------------------------------------------------------------------------- */
+
+static int isp116x_reset(struct isp116x *isp116x);
+
+/* --- Debugging functions ------------------------------------------------- */
+
+#define isp116x_show_reg(d, r) {				\
+	if ((r) < 0x20) {					\
+		DBG("%-12s[%02x]: %08x", #r,			\
+			r, isp116x_read_reg32(d, r));		\
+	} else {						\
+		DBG("%-12s[%02x]:     %04x", #r,		\
+			r, isp116x_read_reg16(d, r));  		\
+	}							\
+}
+
+#define isp116x_show_regs(d) {					\
+	isp116x_show_reg(d, HCREVISION);			\
+	isp116x_show_reg(d, HCCONTROL);				\
+	isp116x_show_reg(d, HCCMDSTAT);				\
+	isp116x_show_reg(d, HCINTSTAT);				\
+	isp116x_show_reg(d, HCINTENB);				\
+	isp116x_show_reg(d, HCFMINTVL);				\
+	isp116x_show_reg(d, HCFMREM);				\
+	isp116x_show_reg(d, HCFMNUM);				\
+	isp116x_show_reg(d, HCLSTHRESH);			\
+	isp116x_show_reg(d, HCRHDESCA);				\
+	isp116x_show_reg(d, HCRHDESCB);				\
+	isp116x_show_reg(d, HCRHSTATUS);			\
+	isp116x_show_reg(d, HCRHPORT1);				\
+	isp116x_show_reg(d, HCRHPORT2);				\
+	isp116x_show_reg(d, HCHWCFG);				\
+	isp116x_show_reg(d, HCDMACFG);				\
+	isp116x_show_reg(d, HCXFERCTR);				\
+	isp116x_show_reg(d, HCuPINT);				\
+	isp116x_show_reg(d, HCuPINTENB);			\
+	isp116x_show_reg(d, HCCHIPID);				\
+	isp116x_show_reg(d, HCSCRATCH);				\
+	isp116x_show_reg(d, HCITLBUFLEN);			\
+	isp116x_show_reg(d, HCATLBUFLEN);			\
+	isp116x_show_reg(d, HCBUFSTAT);				\
+	isp116x_show_reg(d, HCRDITL0LEN);			\
+	isp116x_show_reg(d, HCRDITL1LEN);			\
+}
+
+#if defined(TRACE)
+
+static int isp116x_get_current_frame_number(struct usb_device *usb_dev)
+{
+	struct isp116x *isp116x = &isp116x_dev;
+
+	return isp116x_read_reg32(isp116x, HCFMNUM);
+}
+
+static void dump_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+		     int len, char *str)
+{
+#if defined(VERBOSE)
+	int i;
+#endif
+
+	DBG("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d stat:%#lx",
+	    str,
+	    isp116x_get_current_frame_number(dev),
+	    usb_pipedevice(pipe),
+	    usb_pipeendpoint(pipe),
+	    usb_pipeout(pipe) ? 'O' : 'I',
+	    usb_pipetype(pipe) < 2 ?
+	    (usb_pipeint(pipe) ?
+	     "INTR" : "ISOC") :
+	    (usb_pipecontrol(pipe) ? "CTRL" : "BULK"), len, dev->status);
+#if defined(VERBOSE)
+	if (len > 0 && buffer) {
+		printf(__FILE__ ": data(%d):", len);
+		for (i = 0; i < 16 && i < len; i++)
+			printf(" %02x", ((__u8 *) buffer)[i]);
+		printf("%s\n", i < len ? "..." : "");
+	}
+#endif
+}
+
+#define PTD_DIR_STR(ptd)  ({char __c;		\
+	switch(PTD_GET_DIR(ptd)){		\
+	case 0:  __c = 's'; break;		\
+	case 1:  __c = 'o'; break;		\
+	default: __c = 'i'; break;		\
+	}; __c;})
+
+/*
+  Dump PTD info. The code documents the format
+  perfectly, right :)
+*/
+static inline void dump_ptd(struct ptd *ptd)
+{
+#if defined(VERBOSE)
+	int k;
+#endif
+
+	DBG("PTD(ext) : cc:%x %d%c%d %d,%d,%d t:%x %x%x%x",
+	    PTD_GET_CC(ptd),
+	    PTD_GET_FA(ptd), PTD_DIR_STR(ptd), PTD_GET_EP(ptd),
+	    PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd),
+	    PTD_GET_TOGGLE(ptd),
+	    PTD_GET_ACTIVE(ptd), PTD_GET_SPD(ptd), PTD_GET_LAST(ptd));
+#if defined(VERBOSE)
+	printf("isp116x: %s: PTD(byte): ", __FUNCTION__);
+	for (k = 0; k < sizeof(struct ptd); ++k)
+		printf("%02x ", ((u8 *) ptd)[k]);
+	printf("\n");
+#endif
+}
+
+static inline void dump_ptd_data(struct ptd *ptd, u8 * buf, int type)
+{
+#if defined(VERBOSE)
+	int k;
+
+	if (type == 0 /* 0ut data */ ) {
+		printf("isp116x: %s: out data: ", __FUNCTION__);
+		for (k = 0; k < PTD_GET_LEN(ptd); ++k)
+			printf("%02x ", ((u8 *) buf)[k]);
+		printf("\n");
+	}
+	if (type == 1 /* 1n data */ ) {
+		printf("isp116x: %s: in data: ", __FUNCTION__);
+		for (k = 0; k < PTD_GET_COUNT(ptd); ++k)
+			printf("%02x ", ((u8 *) buf)[k]);
+		printf("\n");
+	}
+
+	if (PTD_GET_LAST(ptd))
+		DBG("--- last PTD ---");
+#endif
+}
+
+#else
+
+#define dump_msg(dev, pipe, buffer, len, str)			do { } while (0)
+#define dump_pkt(dev, pipe, buffer, len, setup, str, small)	do {} while (0)
+
+#define dump_ptd(ptd)			do {} while (0)
+#define dump_ptd_data(ptd, buf, type)	do {} while (0)
+
+#endif
+
+/* --- Virtual Root Hub ---------------------------------------------------- */
+
+/* Device descriptor */
+static __u8 root_hub_dev_des[] = {
+	0x12,			/*  __u8  bLength; */
+	0x01,			/*  __u8  bDescriptorType; Device */
+	0x10,			/*  __u16 bcdUSB; v1.1 */
+	0x01,
+	0x09,			/*  __u8  bDeviceClass; HUB_CLASSCODE */
+	0x00,			/*  __u8  bDeviceSubClass; */
+	0x00,			/*  __u8  bDeviceProtocol; */
+	0x08,			/*  __u8  bMaxPacketSize0; 8 Bytes */
+	0x00,			/*  __u16 idVendor; */
+	0x00,
+	0x00,			/*  __u16 idProduct; */
+	0x00,
+	0x00,			/*  __u16 bcdDevice; */
+	0x00,
+	0x00,			/*  __u8  iManufacturer; */
+	0x01,			/*  __u8  iProduct; */
+	0x00,			/*  __u8  iSerialNumber; */
+	0x01			/*  __u8  bNumConfigurations; */
+};
+
+/* Configuration descriptor */
+static __u8 root_hub_config_des[] = {
+	0x09,			/*  __u8  bLength; */
+	0x02,			/*  __u8  bDescriptorType; Configuration */
+	0x19,			/*  __u16 wTotalLength; */
+	0x00,
+	0x01,			/*  __u8  bNumInterfaces; */
+	0x01,			/*  __u8  bConfigurationValue; */
+	0x00,			/*  __u8  iConfiguration; */
+	0x40,			/*  __u8  bmAttributes;
+				   Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
+	0x00,			/*  __u8  MaxPower; */
+
+	/* interface */
+	0x09,			/*  __u8  if_bLength; */
+	0x04,			/*  __u8  if_bDescriptorType; Interface */
+	0x00,			/*  __u8  if_bInterfaceNumber; */
+	0x00,			/*  __u8  if_bAlternateSetting; */
+	0x01,			/*  __u8  if_bNumEndpoints; */
+	0x09,			/*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
+	0x00,			/*  __u8  if_bInterfaceSubClass; */
+	0x00,			/*  __u8  if_bInterfaceProtocol; */
+	0x00,			/*  __u8  if_iInterface; */
+
+	/* endpoint */
+	0x07,			/*  __u8  ep_bLength; */
+	0x05,			/*  __u8  ep_bDescriptorType; Endpoint */
+	0x81,			/*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
+	0x03,			/*  __u8  ep_bmAttributes; Interrupt */
+	0x00,			/*  __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
+	0x02,
+	0xff			/*  __u8  ep_bInterval; 255 ms */
+};
+
+static unsigned char root_hub_str_index0[] = {
+	0x04,			/*  __u8  bLength; */
+	0x03,			/*  __u8  bDescriptorType; String-descriptor */
+	0x09,			/*  __u8  lang ID */
+	0x04,			/*  __u8  lang ID */
+};
+
+static unsigned char root_hub_str_index1[] = {
+	0x22,			/*  __u8  bLength; */
+	0x03,			/*  __u8  bDescriptorType; String-descriptor */
+	'I',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'S',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'P',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'1',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'1',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'6',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'x',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	' ',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'R',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'o',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'o',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	't',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	' ',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'H',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'u',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'b',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+};
+
+/*
+ * Hub class-specific descriptor is constructed dynamically
+ */
+
+/* --- Virtual root hub management functions ------------------------------- */
+
+static int rh_check_port_status(struct isp116x *isp116x)
+{
+	u32 temp, ndp, i;
+	int res;
+
+	res = -1;
+	temp = isp116x_read_reg32(isp116x, HCRHSTATUS);
+	ndp = (temp & RH_A_NDP);
+	for (i = 0; i < ndp; i++) {
+		temp = isp116x_read_reg32(isp116x, HCRHPORT1 + i);
+		/* check for a device disconnect */
+		if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
+		     (RH_PS_PESC | RH_PS_CSC)) && ((temp & RH_PS_CCS) == 0)) {
+			res = i;
+			break;
+		}
+	}
+	return res;
+}
+
+/* --- HC management functions --------------------------------------------- */
+
+/* Write len bytes to fifo, pad till 32-bit boundary
+ */
+static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
+{
+	u8 *dp = (u8 *) buf;
+	u16 *dp2 = (u16 *) buf;
+	u16 w;
+	int quot = len % 4;
+
+	if ((unsigned long)dp2 & 1) {
+		/* not aligned */
+		for (; len > 1; len -= 2) {
+			w = *dp++;
+			w |= *dp++ << 8;
+			isp116x_raw_write_data16(isp116x, w);
+		}
+		if (len)
+			isp116x_write_data16(isp116x, (u16) * dp);
+	} else {
+		/* aligned */
+		for (; len > 1; len -= 2)
+			isp116x_raw_write_data16(isp116x, *dp2++);
+		if (len)
+			isp116x_write_data16(isp116x, 0xff & *((u8 *) dp2));
+	}
+	if (quot == 1 || quot == 2)
+		isp116x_raw_write_data16(isp116x, 0);
+}
+
+/* Read len bytes from fifo and then read till 32-bit boundary
+ */
+static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
+{
+	u8 *dp = (u8 *) buf;
+	u16 *dp2 = (u16 *) buf;
+	u16 w;
+	int quot = len % 4;
+
+	if ((unsigned long)dp2 & 1) {
+		/* not aligned */
+		for (; len > 1; len -= 2) {
+			w = isp116x_raw_read_data16(isp116x);
+			*dp++ = w & 0xff;
+			*dp++ = (w >> 8) & 0xff;
+		}
+		if (len)
+			*dp = 0xff & isp116x_read_data16(isp116x);
+	} else {
+		/* aligned */
+		for (; len > 1; len -= 2)
+			*dp2++ = isp116x_raw_read_data16(isp116x);
+		if (len)
+			*(u8 *) dp2 = 0xff & isp116x_read_data16(isp116x);
+	}
+	if (quot == 1 || quot == 2)
+		isp116x_raw_read_data16(isp116x);
+}
+
+/* Write PTD's and data for scheduled transfers into the fifo ram.
+ * Fifo must be empty and ready */
+static void pack_fifo(struct isp116x *isp116x, struct usb_device *dev,
+		      unsigned long pipe, struct ptd *ptd, int n, void *data,
+		      int len)
+{
+	int buflen = n * sizeof(struct ptd) + len;
+	int i, done;
+
+	DBG("--- pack buffer %p - %d bytes (fifo %d) ---", data, len, buflen);
+
+	isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
+	isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
+	isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET);
+
+	done = 0;
+	for (i = 0; i < n; i++) {
+		DBG("i=%d - done=%d - len=%d", i, done, PTD_GET_LEN(&ptd[i]));
+
+		dump_ptd(&ptd[i]);
+		isp116x_write_data16(isp116x, ptd[i].count);
+		isp116x_write_data16(isp116x, ptd[i].mps);
+		isp116x_write_data16(isp116x, ptd[i].len);
+		isp116x_write_data16(isp116x, ptd[i].faddr);
+
+		dump_ptd_data(&ptd[i], (__u8 *) data + done, 0);
+		write_ptddata_to_fifo(isp116x,
+				      (__u8 *) data + done,
+				      PTD_GET_LEN(&ptd[i]));
+
+		done += PTD_GET_LEN(&ptd[i]);
+	}
+}
+
+/* Read the processed PTD's and data from fifo ram back to URBs' buffers.
+ * Fifo must be full and done */
+static int unpack_fifo(struct isp116x *isp116x, struct usb_device *dev,
+		       unsigned long pipe, struct ptd *ptd, int n, void *data,
+		       int len)
+{
+	int buflen = n * sizeof(struct ptd) + len;
+	int i, done, cc, ret;
+
+	isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
+	isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
+	isp116x_write_addr(isp116x, HCATLPORT);
+
+	ret = TD_CC_NOERROR;
+	done = 0;
+	for (i = 0; i < n; i++) {
+		DBG("i=%d - done=%d - len=%d", i, done, PTD_GET_LEN(&ptd[i]));
+
+		ptd[i].count = isp116x_read_data16(isp116x);
+		ptd[i].mps = isp116x_read_data16(isp116x);
+		ptd[i].len = isp116x_read_data16(isp116x);
+		ptd[i].faddr = isp116x_read_data16(isp116x);
+		dump_ptd(&ptd[i]);
+
+		read_ptddata_from_fifo(isp116x,
+				       (__u8 *) data + done,
+				       PTD_GET_LEN(&ptd[i]));
+		dump_ptd_data(&ptd[i], (__u8 *) data + done, 1);
+
+		done += PTD_GET_LEN(&ptd[i]);
+
+		cc = PTD_GET_CC(&ptd[i]);
+		if (cc == TD_DATAUNDERRUN) {	/* underrun is no error... */
+			DBG("allowed data underrun");
+			cc = TD_CC_NOERROR;
+		}
+		if (cc != TD_CC_NOERROR && ret == TD_CC_NOERROR)
+			ret = cc;
+	}
+
+	DBG("--- unpack buffer %p - %d bytes (fifo %d) ---", data, len, buflen);
+
+	return ret;
+}
+
+/* Interrupt handling
+ */
+static int isp116x_interrupt(struct isp116x *isp116x)
+{
+	u16 irqstat;
+	u32 intstat;
+	int ret = 0;
+
+	isp116x_write_reg16(isp116x, HCuPINTENB, 0);
+	irqstat = isp116x_read_reg16(isp116x, HCuPINT);
+	isp116x_write_reg16(isp116x, HCuPINT, irqstat);
+	DBG(">>>>>> irqstat %x <<<<<<", irqstat);
+
+	if (irqstat & HCuPINT_ATL) {
+		DBG(">>>>>> HCuPINT_ATL <<<<<<");
+		udelay(500);
+		ret = 1;
+	}
+
+	if (irqstat & HCuPINT_OPR) {
+		intstat = isp116x_read_reg32(isp116x, HCINTSTAT);
+		isp116x_write_reg32(isp116x, HCINTSTAT, intstat);
+		DBG(">>>>>> HCuPINT_OPR %x <<<<<<", intstat);
+
+		if (intstat & HCINT_UE) {
+			ERR("unrecoverable error, controller disabled");
+
+			/* FIXME: be optimistic, hope that bug won't repeat
+			 * often. Make some non-interrupt context restart the
+			 * controller. Count and limit the retries though;
+			 * either hardware or software errors can go forever...
+			 */
+			isp116x_reset(isp116x);
+			ret = -1;
+			return -1;
+		}
+
+		if (intstat & HCINT_RHSC) {
+			got_rhsc = 1;
+			ret = 1;
+			/* When root hub or any of its ports is going
+			   to come out of suspend, it may take more
+			   than 10ms for status bits to stabilize. */
+			wait_ms(20);
+		}
+
+		if (intstat & HCINT_SO) {
+			ERR("schedule overrun");
+			ret = -1;
+		}
+
+		irqstat &= ~HCuPINT_OPR;
+	}
+
+	return ret;
+}
+
+#define PTD_NUM			64	/* it should be enougth... */
+struct ptd ptd[PTD_NUM];
+static inline int max_transfer_len(struct usb_device *dev, unsigned long pipe)
+{
+	return min(PTD_NUM * usb_maxpacket(dev, pipe), PTD_NUM * 16);
+}
+
+/* Do an USB transfer
+ */
+static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
+			      int dir, void *buffer, int len)
+{
+	struct isp116x *isp116x = &isp116x_dev;
+	int type = usb_pipetype(pipe);
+	int epnum = usb_pipeendpoint(pipe);
+	int max = usb_maxpacket(dev, pipe);
+	int dir_out = usb_pipeout(pipe);
+	int speed_low = usb_pipeslow(pipe);
+	int i, done, stat, timeout, cc;
+	int retries = 10;
+
+	DBG("------------------------------------------------");
+	dump_msg(dev, pipe, buffer, len, "SUBMIT");
+	DBG("------------------------------------------------");
+
+	if (isp116x->disabled) {
+		ERR("EPIPE");
+		dev->status = USB_ST_CRC_ERR;
+		return -1;
+	}
+
+	/* device pulled? Shortcut the action. */
+	if (devgone == dev) {
+		ERR("ENODEV");
+		dev->status = USB_ST_CRC_ERR;
+		return USB_ST_CRC_ERR;
+	}
+
+	if (!max) {
+		ERR("pipesize for pipe %lx is zero", pipe);
+		dev->status = USB_ST_CRC_ERR;
+		return -1;
+	}
+
+	if (type == PIPE_ISOCHRONOUS) {
+		ERR("isochronous transfers not supported");
+		dev->status = USB_ST_CRC_ERR;
+		return -1;
+	}
+
+	/* FIFO not empty? */
+	if (isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_FULL) {
+		ERR("****** FIFO not empty! ******");
+		dev->status = USB_ST_BUF_ERR;
+		return -1;
+	}
+
+      retry:
+	isp116x_write_reg32(isp116x, HCINTSTAT, 0xff);
+
+	/* Prepare the PTD data */
+	done = 0;
+	i = 0;
+	do {
+		ptd[i].count = PTD_CC_MSK | PTD_ACTIVE_MSK |
+		    PTD_TOGGLE(usb_gettoggle(dev, epnum, dir_out));
+		ptd[i].mps = PTD_MPS(max) | PTD_SPD(speed_low) | PTD_EP(epnum);
+		ptd[i].len = PTD_LEN(max > len - done ? len - done : max) |
+		    PTD_DIR(dir);
+		ptd[i].faddr = PTD_FA(usb_pipedevice(pipe));
+
+		usb_dotoggle(dev, epnum, dir_out);
+		done += PTD_GET_LEN(&ptd[i]);
+		i++;
+		if (i >= PTD_NUM) {
+			ERR("****** Cannot pack buffer! ******");
+			dev->status = USB_ST_BUF_ERR;
+			return -1;
+		}
+	} while (done < len);
+	ptd[i - 1].mps |= PTD_LAST_MSK;
+
+	/* Pack data into FIFO ram */
+	pack_fifo(isp116x, dev, pipe, ptd, i, buffer, len);
+#ifdef EXTRA_DELAY
+	wait_ms(EXTRA_DELAY);
+#endif
+
+	/* Start the data transfer */
+
+	/* Allow more time for a BULK device to react - some are slow */
+	if (usb_pipetype(pipe) == PIPE_BULK)
+		timeout = 5000;
+	else
+		timeout = 100;
+
+	/* Wait for it to complete */
+	for (;;) {
+		/* Check whether the controller is done */
+		stat = isp116x_interrupt(isp116x);
+
+		if (stat < 0) {
+			dev->status = USB_ST_CRC_ERR;
+			break;
+		}
+		if (stat > 0)
+			break;
+
+		/* Check the timeout */
+		if (--timeout)
+			udelay(1);
+		else {
+			ERR("CTL:TIMEOUT ");
+			stat = USB_ST_CRC_ERR;
+			break;
+		}
+	}
+
+	/* We got an Root Hub Status Change interrupt */
+	if (got_rhsc) {
+		isp116x_show_regs(isp116x);
+
+		got_rhsc = 0;
+
+		/* Abuse timeout */
+		timeout = rh_check_port_status(isp116x);
+		if (timeout >= 0) {
+			/*
+			 * FIXME! NOTE! AAAARGH!
+			 * This is potentially dangerous because it assumes
+			 * that only one device is ever plugged in!
+			 */
+			devgone = dev;
+		}
+	}
+
+	/* Ok, now we can read transfer status */
+
+	/* FIFO not ready? */
+	if (!(isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_DONE)) {
+		ERR("****** FIFO not ready! ******");
+		dev->status = USB_ST_BUF_ERR;
+		return -1;
+	}
+
+	/* Unpack data from FIFO ram */
+	cc = unpack_fifo(isp116x, dev, pipe, ptd, i, buffer, len);
+
+	/* Mmm... sometime we get 0x0f as cc which is a non sense!
+	 * Just retry the transfer...
+	 */
+	if (cc == 0x0f && retries-- > 0) {
+		usb_dotoggle(dev, epnum, dir_out);
+		goto retry;
+	}
+
+	if (cc != TD_CC_NOERROR) {
+		DBG("****** completition code error %x ******", cc);
+		switch (cc) {
+		case TD_CC_BITSTUFFING:
+			dev->status = USB_ST_BIT_ERR;
+			break;
+		case TD_CC_STALL:
+			dev->status = USB_ST_STALLED;
+			break;
+		case TD_BUFFEROVERRUN:
+		case TD_BUFFERUNDERRUN:
+			dev->status = USB_ST_BUF_ERR;
+			break;
+		default:
+			dev->status = USB_ST_CRC_ERR;
+		}
+		return -cc;
+	}
+
+	dump_msg(dev, pipe, buffer, len, "SUBMIT(ret)");
+
+	dev->status = 0;
+	return done;
+}
+
+/* Adapted from au1x00_usb_ohci.c
+ */
+static int isp116x_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+				 void *buffer, int transfer_len,
+				 struct devrequest *cmd)
+{
+	struct isp116x *isp116x = &isp116x_dev;
+	u32 tmp = 0;
+
+	int leni = transfer_len;
+	int len = 0;
+	int stat = 0;
+	u32 datab[4];
+	u8 *data_buf = (u8 *) datab;
+	u16 bmRType_bReq;
+	u16 wValue;
+	u16 wIndex;
+	u16 wLength;
+
+	if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
+		INFO("Root-Hub submit IRQ: NOT implemented");
+		return 0;
+	}
+
+	bmRType_bReq = cmd->requesttype | (cmd->request << 8);
+	wValue = swap_16(cmd->value);
+	wIndex = swap_16(cmd->index);
+	wLength = swap_16(cmd->length);
+
+	DBG("--- HUB ----------------------------------------");
+	DBG("submit rh urb, req=%x val=%#x index=%#x len=%d",
+	    bmRType_bReq, wValue, wIndex, wLength);
+	dump_msg(dev, pipe, buffer, transfer_len, "RH");
+	DBG("------------------------------------------------");
+
+	switch (bmRType_bReq) {
+	case RH_GET_STATUS:
+		DBG("RH_GET_STATUS");
+
+		*(__u16 *) data_buf = swap_16(1);
+		len = 2;
+		break;
+
+	case RH_GET_STATUS | RH_INTERFACE:
+		DBG("RH_GET_STATUS | RH_INTERFACE");
+
+		*(__u16 *) data_buf = swap_16(0);
+		len = 2;
+		break;
+
+	case RH_GET_STATUS | RH_ENDPOINT:
+		DBG("RH_GET_STATUS | RH_ENDPOINT");
+
+		*(__u16 *) data_buf = swap_16(0);
+		len = 2;
+		break;
+
+	case RH_GET_STATUS | RH_CLASS:
+		DBG("RH_GET_STATUS | RH_CLASS");
+
+		tmp = isp116x_read_reg32(isp116x, HCRHSTATUS);
+
+		*(__u32 *) data_buf = swap_32(tmp & ~(RH_HS_CRWE | RH_HS_DRWE));
+		len = 4;
+		break;
+
+	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+		DBG("RH_GET_STATUS | RH_OTHER | RH_CLASS");
+
+		tmp = isp116x_read_reg32(isp116x, HCRHPORT1 + wIndex - 1);
+		*(__u32 *) data_buf = swap_32(tmp);
+		isp116x_show_regs(isp116x);
+		len = 4;
+		break;
+
+	case RH_CLEAR_FEATURE | RH_ENDPOINT:
+		DBG("RH_CLEAR_FEATURE | RH_ENDPOINT");
+
+		switch (wValue) {
+		case RH_ENDPOINT_STALL:
+			DBG("C_HUB_ENDPOINT_STALL");
+			len = 0;
+			break;
+		}
+		break;
+
+	case RH_CLEAR_FEATURE | RH_CLASS:
+		DBG("RH_CLEAR_FEATURE | RH_CLASS");
+
+		switch (wValue) {
+		case RH_C_HUB_LOCAL_POWER:
+			DBG("C_HUB_LOCAL_POWER");
+			len = 0;
+			break;
+
+		case RH_C_HUB_OVER_CURRENT:
+			DBG("C_HUB_OVER_CURRENT");
+			isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_OCIC);
+			len = 0;
+			break;
+		}
+		break;
+
+	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+		DBG("RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS");
+
+		switch (wValue) {
+		case RH_PORT_ENABLE:
+			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+					    RH_PS_CCS);
+			len = 0;
+			break;
+
+		case RH_PORT_SUSPEND:
+			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+					    RH_PS_POCI);
+			len = 0;
+			break;
+
+		case RH_PORT_POWER:
+			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+					    RH_PS_LSDA);
+			len = 0;
+			break;
+
+		case RH_C_PORT_CONNECTION:
+			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+					    RH_PS_CSC);
+			len = 0;
+			break;
+
+		case RH_C_PORT_ENABLE:
+			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+					    RH_PS_PESC);
+			len = 0;
+			break;
+
+		case RH_C_PORT_SUSPEND:
+			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+					    RH_PS_PSSC);
+			len = 0;
+			break;
+
+		case RH_C_PORT_OVER_CURRENT:
+			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+					    RH_PS_POCI);
+			len = 0;
+			break;
+
+		case RH_C_PORT_RESET:
+			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+					    RH_PS_PRSC);
+			len = 0;
+			break;
+
+		default:
+			ERR("invalid wValue");
+			stat = USB_ST_STALLED;
+		}
+
+		isp116x_show_regs(isp116x);
+
+		break;
+
+	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+		DBG("RH_SET_FEATURE | RH_OTHER | RH_CLASS");
+
+		switch (wValue) {
+		case RH_PORT_SUSPEND:
+			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+					    RH_PS_PSS);
+			len = 0;
+			break;
+
+		case RH_PORT_RESET:
+			/* Spin until any current reset finishes */
+			while (1) {
+				tmp =
+				    isp116x_read_reg32(isp116x,
+						       HCRHPORT1 + wIndex - 1);
+				if (!(tmp & RH_PS_PRS))
+					break;
+				wait_ms(1);
+			}
+			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+					    RH_PS_PRS);
+			wait_ms(10);
+
+			len = 0;
+			break;
+
+		case RH_PORT_POWER:
+			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+					    RH_PS_PPS);
+			len = 0;
+			break;
+
+		case RH_PORT_ENABLE:
+			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+					    RH_PS_PES);
+			len = 0;
+			break;
+
+		default:
+			ERR("invalid wValue");
+			stat = USB_ST_STALLED;
+		}
+
+		isp116x_show_regs(isp116x);
+
+		break;
+
+	case RH_SET_ADDRESS:
+		DBG("RH_SET_ADDRESS");
+
+		rh_devnum = wValue;
+		len = 0;
+		break;
+
+	case RH_GET_DESCRIPTOR:
+		DBG("RH_GET_DESCRIPTOR: %x, %d", wValue, wLength);
+
+		switch (wValue) {
+		case (USB_DT_DEVICE << 8):	/* device descriptor */
+			len = min_t(unsigned int,
+				    leni, min_t(unsigned int,
+						sizeof(root_hub_dev_des),
+						wLength));
+			data_buf = root_hub_dev_des;
+			break;
+
+		case (USB_DT_CONFIG << 8):	/* configuration descriptor */
+			len = min_t(unsigned int,
+				    leni, min_t(unsigned int,
+						sizeof(root_hub_config_des),
+						wLength));
+			data_buf = root_hub_config_des;
+			break;
+
+		case ((USB_DT_STRING << 8) | 0x00):	/* string 0 descriptors */
+			len = min_t(unsigned int,
+				    leni, min_t(unsigned int,
+						sizeof(root_hub_str_index0),
+						wLength));
+			data_buf = root_hub_str_index0;
+			break;
+
+		case ((USB_DT_STRING << 8) | 0x01):	/* string 1 descriptors */
+			len = min_t(unsigned int,
+				    leni, min_t(unsigned int,
+						sizeof(root_hub_str_index1),
+						wLength));
+			data_buf = root_hub_str_index1;
+			break;
+
+		default:
+			ERR("invalid wValue");
+			stat = USB_ST_STALLED;
+		}
+
+		break;
+
+	case RH_GET_DESCRIPTOR | RH_CLASS:
+		DBG("RH_GET_DESCRIPTOR | RH_CLASS");
+
+		tmp = isp116x_read_reg32(isp116x, HCRHDESCA);
+
+		data_buf[0] = 0x09;	/* min length; */
+		data_buf[1] = 0x29;
+		data_buf[2] = tmp & RH_A_NDP;
+		data_buf[3] = 0;
+		if (tmp & RH_A_PSM)	/* per-port power switching? */
+			data_buf[3] |= 0x01;
+		if (tmp & RH_A_NOCP)	/* no overcurrent reporting? */
+			data_buf[3] |= 0x10;
+		else if (tmp & RH_A_OCPM)	/* per-port overcurrent rep? */
+			data_buf[3] |= 0x08;
+
+		/* Corresponds to data_buf[4-7] */
+		datab[1] = 0;
+		data_buf[5] = (tmp & RH_A_POTPGT) >> 24;
+
+		tmp = isp116x_read_reg32(isp116x, HCRHDESCB);
+
+		data_buf[7] = tmp & RH_B_DR;
+		if (data_buf[2] < 7)
+			data_buf[8] = 0xff;
+		else {
+			data_buf[0] += 2;
+			data_buf[8] = (tmp & RH_B_DR) >> 8;
+			data_buf[10] = data_buf[9] = 0xff;
+		}
+
+		len = min_t(unsigned int, leni,
+			    min_t(unsigned int, data_buf[0], wLength));
+		break;
+
+	case RH_GET_CONFIGURATION:
+		DBG("RH_GET_CONFIGURATION");
+
+		*(__u8 *) data_buf = 0x01;
+		len = 1;
+		break;
+
+	case RH_SET_CONFIGURATION:
+		DBG("RH_SET_CONFIGURATION");
+
+		isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPSC);
+		len = 0;
+		break;
+
+	default:
+		ERR("*** *** *** unsupported root hub command *** *** ***");
+		stat = USB_ST_STALLED;
+	}
+
+	len = min_t(int, len, leni);
+	if (buffer != data_buf)
+		memcpy(buffer, data_buf, len);
+
+	dev->act_len = len;
+	dev->status = stat;
+	DBG("dev act_len %d, status %d", dev->act_len, dev->status);
+
+	dump_msg(dev, pipe, buffer, transfer_len, "RH(ret)");
+
+	return stat;
+}
+
+/* --- Transfer functions -------------------------------------------------- */
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+		   int len, int interval)
+{
+	DBG("dev=%p pipe=%#lx buf=%p size=%d int=%d",
+	    dev, pipe, buffer, len, interval);
+
+	return -1;
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+		       int len, struct devrequest *setup)
+{
+	int devnum = usb_pipedevice(pipe);
+	int epnum = usb_pipeendpoint(pipe);
+	int max = max_transfer_len(dev, pipe);
+	int dir_in = usb_pipein(pipe);
+	int done, ret;
+
+	/* Control message is for the HUB? */
+	if (devnum == rh_devnum)
+		return isp116x_submit_rh_msg(dev, pipe, buffer, len, setup);
+
+	/* Ok, no HUB message so send the message to the device */
+
+	/* Setup phase */
+	DBG("--- SETUP PHASE --------------------------------");
+	usb_settoggle(dev, epnum, 1, 0);
+	ret = isp116x_submit_job(dev, pipe,
+				 PTD_DIR_SETUP,
+				 setup, sizeof(struct devrequest));
+	if (ret < 0) {
+		DBG("control setup phase error (ret = %d", ret);
+		return -1;
+	}
+
+	/* Data phase */
+	DBG("--- DATA PHASE ---------------------------------");
+	done = 0;
+	usb_settoggle(dev, epnum, !dir_in, 1);
+	while (done < len) {
+		ret = isp116x_submit_job(dev, pipe,
+					 dir_in ? PTD_DIR_IN : PTD_DIR_OUT,
+					 (__u8 *) buffer + done,
+					 max > len - done ? len - done : max);
+		if (ret < 0) {
+			DBG("control data phase error (ret = %d)", ret);
+			return -1;
+		}
+		done += ret;
+
+		if (dir_in && ret < max)	/* short packet */
+			break;
+	}
+
+	/* Status phase */
+	DBG("--- STATUS PHASE -------------------------------");
+	usb_settoggle(dev, epnum, !dir_in, 1);
+	ret = isp116x_submit_job(dev, pipe,
+				 !dir_in ? PTD_DIR_IN : PTD_DIR_OUT, NULL, 0);
+	if (ret < 0) {
+		DBG("control status phase error (ret = %d", ret);
+		return -1;
+	}
+
+	dev->act_len = done;
+
+	dump_msg(dev, pipe, buffer, len, "DEV(ret)");
+
+	return done;
+}
+
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+		    int len)
+{
+	int dir_out = usb_pipeout(pipe);
+	int max = max_transfer_len(dev, pipe);
+	int done, ret;
+
+	DBG("--- BULK ---------------------------------------");
+	DBG("dev=%ld pipe=%ld buf=%p size=%d dir_out=%d",
+	    usb_pipedevice(pipe), usb_pipeendpoint(pipe), buffer, len, dir_out);
+
+	done = 0;
+	while (done < len) {
+		ret = isp116x_submit_job(dev, pipe,
+					 !dir_out ? PTD_DIR_IN : PTD_DIR_OUT,
+					 (__u8 *) buffer + done,
+					 max > len - done ? len - done : max);
+		if (ret < 0) {
+			DBG("error on bulk message (ret = %d)", ret);
+			return -1;
+		}
+
+		done += ret;
+
+		if (!dir_out && ret < max)	/* short packet */
+			break;
+	}
+
+	dev->act_len = done;
+
+	return 0;
+}
+
+/* --- Basic functions ----------------------------------------------------- */
+
+static int isp116x_sw_reset(struct isp116x *isp116x)
+{
+	int retries = 15;
+	int ret = 0;
+
+	DBG("");
+
+	isp116x->disabled = 1;
+
+	isp116x_write_reg16(isp116x, HCSWRES, HCSWRES_MAGIC);
+	isp116x_write_reg32(isp116x, HCCMDSTAT, HCCMDSTAT_HCR);
+	while (--retries) {
+		/* It usually resets within 1 ms */
+		wait_ms(1);
+		if (!(isp116x_read_reg32(isp116x, HCCMDSTAT) & HCCMDSTAT_HCR))
+			break;
+	}
+	if (!retries) {
+		ERR("software reset timeout");
+		ret = -1;
+	}
+	return ret;
+}
+
+static int isp116x_reset(struct isp116x *isp116x)
+{
+	unsigned long t;
+	u16 clkrdy = 0;
+	int ret, timeout = 15 /* ms */ ;
+
+	DBG("");
+
+	ret = isp116x_sw_reset(isp116x);
+	if (ret)
+		return ret;
+
+	for (t = 0; t < timeout; t++) {
+		clkrdy = isp116x_read_reg16(isp116x, HCuPINT) & HCuPINT_CLKRDY;
+		if (clkrdy)
+			break;
+		wait_ms(1);
+	}
+	if (!clkrdy) {
+		ERR("clock not ready after %dms", timeout);
+		/* After sw_reset the clock won't report to be ready, if
+		   H_WAKEUP pin is high. */
+		ERR("please make sure that the H_WAKEUP pin is pulled low!");
+		ret = -1;
+	}
+	return ret;
+}
+
+static void isp116x_stop(struct isp116x *isp116x)
+{
+	u32 val;
+
+	DBG("");
+
+	isp116x_write_reg16(isp116x, HCuPINTENB, 0);
+
+	/* Switch off ports' power, some devices don't come up
+	   after next 'start' without this */
+	val = isp116x_read_reg32(isp116x, HCRHDESCA);
+	val &= ~(RH_A_NPS | RH_A_PSM);
+	isp116x_write_reg32(isp116x, HCRHDESCA, val);
+	isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS);
+
+	isp116x_sw_reset(isp116x);
+}
+
+/*
+ *  Configure the chip. The chip must be successfully reset by now.
+ */
+static int isp116x_start(struct isp116x *isp116x)
+{
+	struct isp116x_platform_data *board = isp116x->board;
+	u32 val;
+
+	DBG("");
+
+	/* Clear interrupt status and disable all interrupt sources */
+	isp116x_write_reg16(isp116x, HCuPINT, 0xff);
+	isp116x_write_reg16(isp116x, HCuPINTENB, 0);
+
+	isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE);
+	isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE);
+
+	/* Hardware configuration */
+	val = HCHWCFG_DBWIDTH(1);
+	if (board->sel15Kres)
+		val |= HCHWCFG_15KRSEL;
+	/* Remote wakeup won't work without working clock */
+	if (board->remote_wakeup_enable)
+		val |= HCHWCFG_CLKNOTSTOP;
+	if (board->oc_enable)
+		val |= HCHWCFG_ANALOG_OC;
+	isp116x_write_reg16(isp116x, HCHWCFG, val);
+
+	/* --- Root hub configuration */
+	val = (25 << 24) & RH_A_POTPGT;
+	/* AN10003_1.pdf recommends RH_A_NPS (no power switching) to
+	   be always set. Yet, instead, we request individual port
+	   power switching. */
+	val |= RH_A_PSM;
+	/* Report overcurrent per port */
+	val |= RH_A_OCPM;
+	isp116x_write_reg32(isp116x, HCRHDESCA, val);
+	isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA);
+
+	val = RH_B_PPCM;
+	isp116x_write_reg32(isp116x, HCRHDESCB, val);
+	isp116x->rhdescb = isp116x_read_reg32(isp116x, HCRHDESCB);
+
+	val = 0;
+	if (board->remote_wakeup_enable)
+		val |= RH_HS_DRWE;
+	isp116x_write_reg32(isp116x, HCRHSTATUS, val);
+	isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);
+
+	isp116x_write_reg32(isp116x, HCFMINTVL, 0x27782edf);
+
+	/* Go operational */
+	val = HCCONTROL_USB_OPER;
+	if (board->remote_wakeup_enable)
+		val |= HCCONTROL_RWE;
+	isp116x_write_reg32(isp116x, HCCONTROL, val);
+
+	/* Disable ports to avoid race in device enumeration */
+	isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS);
+	isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS);
+
+	isp116x_show_regs(isp116x);
+
+	isp116x->disabled = 0;
+
+	return 0;
+}
+
+/* --- Init functions ------------------------------------------------------ */
+
+int isp116x_check_id(struct isp116x *isp116x)
+{
+	int val;
+
+	val = isp116x_read_reg16(isp116x, HCCHIPID);
+	if ((val & HCCHIPID_MASK) != HCCHIPID_MAGIC) {
+		ERR("invalid chip ID %04x", val);
+		return -1;
+	}
+
+	return 0;
+}
+
+int usb_lowlevel_init(void)
+{
+	struct isp116x *isp116x = &isp116x_dev;
+
+	DBG("");
+
+	/* Init device registers addr */
+	isp116x->addr_reg = (u16 *) ISP116X_HCD_ADDR;
+	isp116x->data_reg = (u16 *) ISP116X_HCD_DATA;
+
+	/* Setup specific board settings */
+#ifdef ISP116X_HCD_SEL15kRES
+	isp116x_board.sel15Kres = 1;
+#endif
+#ifdef ISP116X_HCD_OC_ENABLE
+	isp116x_board.oc_enable = 1;
+#endif
+#ifdef ISP116X_HCD_REMOTE_WAKEUP_ENABLE
+	isp116x_board.remote_wakeup_enable = 1;
+#endif
+	isp116x->board = &isp116x_board;
+
+	/* Try to get ISP116x silicon chip ID */
+	if (isp116x_check_id(isp116x) < 0)
+		return -1;
+
+	isp116x->disabled = 1;
+	isp116x->sleeping = 0;
+
+	isp116x_reset(isp116x);
+	isp116x_start(isp116x);
+
+	return 0;
+}
+
+int usb_lowlevel_stop(void)
+{
+	struct isp116x *isp116x = &isp116x_dev;
+
+	DBG("");
+
+	if (!isp116x->disabled)
+		isp116x_stop(isp116x);
+
+	return 0;
+}
+
+#endif				/* CONFIG_USB_ISP116X_HCD */
diff --git a/drivers/isp116x.h b/drivers/isp116x.h
new file mode 100644
index 0000000000000000000000000000000000000000..a3ce3b582c7c8ea695d9023e358b58be27cc4142
--- /dev/null
+++ b/drivers/isp116x.h
@@ -0,0 +1,489 @@
+/*
+ * ISP116x register declarations and HCD data structures
+ *
+ * Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
+ * Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
+ * Copyright (C) 2005 Olav Kongas <ok@artecdesign.ee>
+ * Portions:
+ * Copyright (C) 2004 Lothar Wassmann
+ * Copyright (C) 2004 Psion Teklogix
+ * Copyright (C) 2004 David Brownell
+ *
+ * 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
+ */
+
+#ifdef DEBUG
+#define DBG(fmt, args...)	\
+		printf("isp116x: %s: " fmt "\n" , __FUNCTION__ , ## args)
+#else
+#define DBG(fmt, args...)	do {} while (0)
+#endif
+
+#ifdef VERBOSE
+#    define VDBG		DBG
+#else
+#    define VDBG(fmt, args...)	do {} while (0)
+#endif
+
+#define ERR(fmt, args...)	\
+		printf("isp116x: %s: " fmt "\n" , __FUNCTION__ , ## args)
+#define WARN(fmt, args...)	\
+		printf("isp116x: %s: " fmt "\n" , __FUNCTION__ , ## args)
+#define INFO(fmt, args...)	\
+		printf("isp116x: " fmt "\n" , ## args)
+
+/* ------------------------------------------------------------------------- */
+
+/* us of 1ms frame */
+#define  MAX_LOAD_LIMIT		850
+
+/* Full speed: max # of bytes to transfer for a single urb
+   at a time must be < 1024 && must be multiple of 64.
+   832 allows transfering 4kiB within 5 frames. */
+#define MAX_TRANSFER_SIZE_FULLSPEED	832
+
+/* Low speed: there is no reason to schedule in very big
+   chunks; often the requested long transfers are for
+   string descriptors containing short strings. */
+#define MAX_TRANSFER_SIZE_LOWSPEED	64
+
+/* Bytetime (us), a rough indication of how much time it
+   would take to transfer a byte of useful data over USB */
+#define BYTE_TIME_FULLSPEED	1
+#define BYTE_TIME_LOWSPEED	20
+
+/* Buffer sizes */
+#define ISP116x_BUF_SIZE	4096
+#define ISP116x_ITL_BUFSIZE	0
+#define ISP116x_ATL_BUFSIZE	((ISP116x_BUF_SIZE) - 2*(ISP116x_ITL_BUFSIZE))
+
+#define ISP116x_WRITE_OFFSET	0x80
+
+/* --- ISP116x registers/bits ---------------------------------------------- */
+
+#define	HCREVISION	0x00
+#define	HCCONTROL	0x01
+#define		HCCONTROL_HCFS	(3 << 6)	/* host controller
+						   functional state */
+#define		HCCONTROL_USB_RESET	(0 << 6)
+#define		HCCONTROL_USB_RESUME	(1 << 6)
+#define		HCCONTROL_USB_OPER	(2 << 6)
+#define		HCCONTROL_USB_SUSPEND	(3 << 6)
+#define		HCCONTROL_RWC	(1 << 9)	/* remote wakeup connected */
+#define		HCCONTROL_RWE	(1 << 10)	/* remote wakeup enable */
+#define	HCCMDSTAT	0x02
+#define		HCCMDSTAT_HCR	(1 << 0)	/* host controller reset */
+#define		HCCMDSTAT_SOC	(3 << 16)	/* scheduling overrun count */
+#define	HCINTSTAT	0x03
+#define		HCINT_SO	(1 << 0)	/* scheduling overrun */
+#define		HCINT_WDH	(1 << 1)	/* writeback of done_head */
+#define		HCINT_SF	(1 << 2)	/* start frame */
+#define		HCINT_RD	(1 << 3)	/* resume detect */
+#define		HCINT_UE	(1 << 4)	/* unrecoverable error */
+#define		HCINT_FNO	(1 << 5)	/* frame number overflow */
+#define		HCINT_RHSC	(1 << 6)	/* root hub status change */
+#define		HCINT_OC	(1 << 30)	/* ownership change */
+#define		HCINT_MIE	(1 << 31)	/* master interrupt enable */
+#define	HCINTENB	0x04
+#define	HCINTDIS	0x05
+#define	HCFMINTVL	0x0d
+#define	HCFMREM		0x0e
+#define	HCFMNUM		0x0f
+#define	HCLSTHRESH	0x11
+#define	HCRHDESCA	0x12
+#define		RH_A_NDP	(0x3 << 0)	/* # downstream ports */
+#define		RH_A_PSM	(1 << 8)	/* power switching mode */
+#define		RH_A_NPS	(1 << 9)	/* no power switching */
+#define		RH_A_DT		(1 << 10)	/* device type (mbz) */
+#define		RH_A_OCPM	(1 << 11)	/* overcurrent protection
+						   mode */
+#define		RH_A_NOCP	(1 << 12)	/* no overcurrent protection */
+#define		RH_A_POTPGT	(0xff << 24)	/* power on -> power good
+						   time */
+#define	HCRHDESCB	0x13
+#define		RH_B_DR		(0xffff << 0)	/* device removable flags */
+#define		RH_B_PPCM	(0xffff << 16)	/* port power control mask */
+#define	HCRHSTATUS	0x14
+#define		RH_HS_LPS	(1 << 0)	/* local power status */
+#define		RH_HS_OCI	(1 << 1)	/* over current indicator */
+#define		RH_HS_DRWE	(1 << 15)	/* device remote wakeup
+						   enable */
+#define		RH_HS_LPSC	(1 << 16)	/* local power status change */
+#define		RH_HS_OCIC	(1 << 17)	/* over current indicator
+						   change */
+#define		RH_HS_CRWE	(1 << 31)	/* clear remote wakeup
+						   enable */
+#define	HCRHPORT1	0x15
+#define		RH_PS_CCS	(1 << 0)	/* current connect status */
+#define		RH_PS_PES	(1 << 1)	/* port enable status */
+#define		RH_PS_PSS	(1 << 2)	/* port suspend status */
+#define		RH_PS_POCI	(1 << 3)	/* port over current
+						   indicator */
+#define		RH_PS_PRS	(1 << 4)	/* port reset status */
+#define		RH_PS_PPS	(1 << 8)	/* port power status */
+#define		RH_PS_LSDA	(1 << 9)	/* low speed device attached */
+#define		RH_PS_CSC	(1 << 16)	/* connect status change */
+#define		RH_PS_PESC	(1 << 17)	/* port enable status change */
+#define		RH_PS_PSSC	(1 << 18)	/* port suspend status
+						   change */
+#define		RH_PS_OCIC	(1 << 19)	/* over current indicator
+						   change */
+#define		RH_PS_PRSC	(1 << 20)	/* port reset status change */
+#define		HCRHPORT_CLRMASK	(0x1f << 16)
+#define	HCRHPORT2	0x16
+#define	HCHWCFG		0x20
+#define		HCHWCFG_15KRSEL		(1 << 12)
+#define		HCHWCFG_CLKNOTSTOP	(1 << 11)
+#define		HCHWCFG_ANALOG_OC	(1 << 10)
+#define		HCHWCFG_DACK_MODE	(1 << 8)
+#define		HCHWCFG_EOT_POL		(1 << 7)
+#define		HCHWCFG_DACK_POL	(1 << 6)
+#define		HCHWCFG_DREQ_POL	(1 << 5)
+#define		HCHWCFG_DBWIDTH_MASK	(0x03 << 3)
+#define		HCHWCFG_DBWIDTH(n)	(((n) << 3) & HCHWCFG_DBWIDTH_MASK)
+#define		HCHWCFG_INT_POL		(1 << 2)
+#define		HCHWCFG_INT_TRIGGER	(1 << 1)
+#define		HCHWCFG_INT_ENABLE	(1 << 0)
+#define	HCDMACFG	0x21
+#define		HCDMACFG_BURST_LEN_MASK	(0x03 << 5)
+#define		HCDMACFG_BURST_LEN(n)	(((n) << 5) & HCDMACFG_BURST_LEN_MASK)
+#define		HCDMACFG_BURST_LEN_1	HCDMACFG_BURST_LEN(0)
+#define		HCDMACFG_BURST_LEN_4	HCDMACFG_BURST_LEN(1)
+#define		HCDMACFG_BURST_LEN_8	HCDMACFG_BURST_LEN(2)
+#define		HCDMACFG_DMA_ENABLE	(1 << 4)
+#define		HCDMACFG_BUF_TYPE_MASK	(0x07 << 1)
+#define		HCDMACFG_CTR_SEL	(1 << 2)
+#define		HCDMACFG_ITLATL_SEL	(1 << 1)
+#define		HCDMACFG_DMA_RW_SELECT	(1 << 0)
+#define	HCXFERCTR	0x22
+#define	HCuPINT		0x24
+#define		HCuPINT_SOF		(1 << 0)
+#define		HCuPINT_ATL		(1 << 1)
+#define		HCuPINT_AIIEOT		(1 << 2)
+#define		HCuPINT_OPR		(1 << 4)
+#define		HCuPINT_SUSP		(1 << 5)
+#define		HCuPINT_CLKRDY		(1 << 6)
+#define	HCuPINTENB	0x25
+#define	HCCHIPID	0x27
+#define		HCCHIPID_MASK		0xff00
+#define		HCCHIPID_MAGIC		0x6100
+#define	HCSCRATCH	0x28
+#define	HCSWRES		0x29
+#define		HCSWRES_MAGIC		0x00f6
+#define	HCITLBUFLEN	0x2a
+#define	HCATLBUFLEN	0x2b
+#define	HCBUFSTAT	0x2c
+#define		HCBUFSTAT_ITL0_FULL	(1 << 0)
+#define		HCBUFSTAT_ITL1_FULL	(1 << 1)
+#define		HCBUFSTAT_ATL_FULL	(1 << 2)
+#define		HCBUFSTAT_ITL0_DONE	(1 << 3)
+#define		HCBUFSTAT_ITL1_DONE	(1 << 4)
+#define		HCBUFSTAT_ATL_DONE	(1 << 5)
+#define	HCRDITL0LEN	0x2d
+#define	HCRDITL1LEN	0x2e
+#define	HCITLPORT	0x40
+#define	HCATLPORT	0x41
+
+/* PTD accessor macros. */
+#define PTD_GET_COUNT(p)	(((p)->count & PTD_COUNT_MSK) >> 0)
+#define PTD_COUNT(v)		(((v) << 0) & PTD_COUNT_MSK)
+#define PTD_GET_TOGGLE(p)	(((p)->count & PTD_TOGGLE_MSK) >> 10)
+#define PTD_TOGGLE(v)		(((v) << 10) & PTD_TOGGLE_MSK)
+#define PTD_GET_ACTIVE(p)	(((p)->count & PTD_ACTIVE_MSK) >> 11)
+#define PTD_ACTIVE(v)		(((v) << 11) & PTD_ACTIVE_MSK)
+#define PTD_GET_CC(p)		(((p)->count & PTD_CC_MSK) >> 12)
+#define PTD_CC(v)		(((v) << 12) & PTD_CC_MSK)
+#define PTD_GET_MPS(p)		(((p)->mps & PTD_MPS_MSK) >> 0)
+#define PTD_MPS(v)		(((v) << 0) & PTD_MPS_MSK)
+#define PTD_GET_SPD(p)		(((p)->mps & PTD_SPD_MSK) >> 10)
+#define PTD_SPD(v)		(((v) << 10) & PTD_SPD_MSK)
+#define PTD_GET_LAST(p)		(((p)->mps & PTD_LAST_MSK) >> 11)
+#define PTD_LAST(v)		(((v) << 11) & PTD_LAST_MSK)
+#define PTD_GET_EP(p)		(((p)->mps & PTD_EP_MSK) >> 12)
+#define PTD_EP(v)		(((v) << 12) & PTD_EP_MSK)
+#define PTD_GET_LEN(p)		(((p)->len & PTD_LEN_MSK) >> 0)
+#define PTD_LEN(v)		(((v) << 0) & PTD_LEN_MSK)
+#define PTD_GET_DIR(p)		(((p)->len & PTD_DIR_MSK) >> 10)
+#define PTD_DIR(v)		(((v) << 10) & PTD_DIR_MSK)
+#define PTD_GET_B5_5(p)		(((p)->len & PTD_B5_5_MSK) >> 13)
+#define PTD_B5_5(v)		(((v) << 13) & PTD_B5_5_MSK)
+#define PTD_GET_FA(p)		(((p)->faddr & PTD_FA_MSK) >> 0)
+#define PTD_FA(v)		(((v) << 0) & PTD_FA_MSK)
+#define PTD_GET_FMT(p)		(((p)->faddr & PTD_FMT_MSK) >> 7)
+#define PTD_FMT(v)		(((v) << 7) & PTD_FMT_MSK)
+
+/*  Hardware transfer status codes -- CC from ptd->count */
+#define TD_CC_NOERROR      0x00
+#define TD_CC_CRC          0x01
+#define TD_CC_BITSTUFFING  0x02
+#define TD_CC_DATATOGGLEM  0x03
+#define TD_CC_STALL        0x04
+#define TD_DEVNOTRESP      0x05
+#define TD_PIDCHECKFAIL    0x06
+#define TD_UNEXPECTEDPID   0x07
+#define TD_DATAOVERRUN     0x08
+#define TD_DATAUNDERRUN    0x09
+    /* 0x0A, 0x0B reserved for hardware */
+#define TD_BUFFEROVERRUN   0x0C
+#define TD_BUFFERUNDERRUN  0x0D
+    /* 0x0E, 0x0F reserved for HCD */
+#define TD_NOTACCESSED     0x0F
+
+/* ------------------------------------------------------------------------- */
+
+#define	LOG2_PERIODIC_SIZE	5	/* arbitrary; this matches OHCI */
+#define	PERIODIC_SIZE		(1 << LOG2_PERIODIC_SIZE)
+
+/* Philips transfer descriptor */
+struct ptd {
+	u16 count;
+#define	PTD_COUNT_MSK	(0x3ff << 0)
+#define	PTD_TOGGLE_MSK	(1 << 10)
+#define	PTD_ACTIVE_MSK	(1 << 11)
+#define	PTD_CC_MSK	(0xf << 12)
+	u16 mps;
+#define	PTD_MPS_MSK	(0x3ff << 0)
+#define	PTD_SPD_MSK	(1 << 10)
+#define	PTD_LAST_MSK	(1 << 11)
+#define	PTD_EP_MSK	(0xf << 12)
+	u16 len;
+#define	PTD_LEN_MSK	(0x3ff << 0)
+#define	PTD_DIR_MSK	(3 << 10)
+#define	PTD_DIR_SETUP	(0)
+#define	PTD_DIR_OUT	(1)
+#define	PTD_DIR_IN	(2)
+#define	PTD_B5_5_MSK	(1 << 13)
+	u16 faddr;
+#define	PTD_FA_MSK	(0x7f << 0)
+#define	PTD_FMT_MSK	(1 << 7)
+} __attribute__ ((packed, aligned(2)));
+
+struct isp116x_ep {
+	struct usb_device *udev;
+	struct ptd ptd;
+
+	u8 maxpacket;
+	u8 epnum;
+	u8 nextpid;
+
+	u16 length;		/* of current packet */
+	unsigned char *data;	/* to databuf */
+
+	u16 error_count;
+};
+
+/* URB struct */
+#define N_URB_TD		48
+#define URB_DEL			1
+typedef struct {
+	struct isp116x_ep *ed;
+	void *transfer_buffer;	/* (in) associated data buffer */
+	int actual_length;	/* (return) actual transfer length */
+	unsigned long pipe;	/* (in) pipe information */
+#if 0
+	int state;
+#endif
+} urb_priv_t;
+
+struct isp116x_platform_data {
+	/* Enable internal resistors on downstream ports */
+	unsigned sel15Kres:1;
+	/* On-chip overcurrent detection */
+	unsigned oc_enable:1;
+	/* Enable wakeup by devices on usb bus (e.g. wakeup
+	   by attachment/detachment or by device activity
+	   such as moving a mouse). When chosen, this option
+	   prevents stopping internal clock, increasing
+	   thereby power consumption in suspended state. */
+	unsigned remote_wakeup_enable:1;
+};
+
+struct isp116x {
+	u16 *addr_reg;
+	u16 *data_reg;
+
+	struct isp116x_platform_data *board;
+
+	struct dentry *dentry;
+	unsigned long stat1, stat2, stat4, stat8, stat16;
+
+	/* Status flags */
+	unsigned disabled:1;
+	unsigned sleeping:1;
+
+	/* Root hub registers */
+	u32 rhdesca;
+	u32 rhdescb;
+	u32 rhstatus;
+	u32 rhport[2];
+
+	/* Schedule for the current frame */
+	struct isp116x_ep *atl_active;
+	int atl_buflen;
+	int atl_bufshrt;
+	int atl_last_dir;
+	int atl_finishing;
+};
+
+/* ------------------------------------------------- */
+
+/* Inter-io delay (ns). The chip is picky about access timings; it
+ * expects at least:
+ * 150ns delay between consecutive accesses to DATA_REG,
+ * 300ns delay between access to ADDR_REG and DATA_REG
+ * OE, WE MUST NOT be changed during these intervals
+ */
+#if defined(UDELAY)
+#define	isp116x_delay(h,d)	udelay(d)
+#else
+#define	isp116x_delay(h,d)	do {} while (0)
+#endif
+
+static inline void isp116x_write_addr(struct isp116x *isp116x, unsigned reg)
+{
+	writew(reg & 0xff, isp116x->addr_reg);
+	isp116x_delay(isp116x, UDELAY);
+}
+
+static inline void isp116x_write_data16(struct isp116x *isp116x, u16 val)
+{
+	writew(val, isp116x->data_reg);
+	isp116x_delay(isp116x, UDELAY);
+}
+
+static inline void isp116x_raw_write_data16(struct isp116x *isp116x, u16 val)
+{
+	__raw_writew(val, isp116x->data_reg);
+	isp116x_delay(isp116x, UDELAY);
+}
+
+static inline u16 isp116x_read_data16(struct isp116x *isp116x)
+{
+	u16 val;
+
+	val = readw(isp116x->data_reg);
+	isp116x_delay(isp116x, UDELAY);
+	return val;
+}
+
+static inline u16 isp116x_raw_read_data16(struct isp116x *isp116x)
+{
+	u16 val;
+
+	val = __raw_readw(isp116x->data_reg);
+	isp116x_delay(isp116x, UDELAY);
+	return val;
+}
+
+static inline void isp116x_write_data32(struct isp116x *isp116x, u32 val)
+{
+	writew(val & 0xffff, isp116x->data_reg);
+	isp116x_delay(isp116x, UDELAY);
+	writew(val >> 16, isp116x->data_reg);
+	isp116x_delay(isp116x, UDELAY);
+}
+
+static inline u32 isp116x_read_data32(struct isp116x *isp116x)
+{
+	u32 val;
+
+	val = (u32) readw(isp116x->data_reg);
+	isp116x_delay(isp116x, UDELAY);
+	val |= ((u32) readw(isp116x->data_reg)) << 16;
+	isp116x_delay(isp116x, UDELAY);
+	return val;
+}
+
+/* Let's keep register access functions out of line. Hint:
+   we wait at least 150 ns at every access.
+*/
+static u16 isp116x_read_reg16(struct isp116x *isp116x, unsigned reg)
+{
+	isp116x_write_addr(isp116x, reg);
+	return isp116x_read_data16(isp116x);
+}
+
+static u32 isp116x_read_reg32(struct isp116x *isp116x, unsigned reg)
+{
+	isp116x_write_addr(isp116x, reg);
+	return isp116x_read_data32(isp116x);
+}
+
+static void isp116x_write_reg16(struct isp116x *isp116x, unsigned reg,
+				unsigned val)
+{
+	isp116x_write_addr(isp116x, reg | ISP116x_WRITE_OFFSET);
+	isp116x_write_data16(isp116x, (u16) (val & 0xffff));
+}
+
+static void isp116x_write_reg32(struct isp116x *isp116x, unsigned reg,
+				unsigned val)
+{
+	isp116x_write_addr(isp116x, reg | ISP116x_WRITE_OFFSET);
+	isp116x_write_data32(isp116x, (u32) val);
+}
+
+/* --- USB HUB constants (not OHCI-specific; see hub.h) -------------------- */
+
+/* destination of request */
+#define RH_INTERFACE               0x01
+#define RH_ENDPOINT                0x02
+#define RH_OTHER                   0x03
+
+#define RH_CLASS                   0x20
+#define RH_VENDOR                  0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS           0x0080
+#define RH_CLEAR_FEATURE        0x0100
+#define RH_SET_FEATURE          0x0300
+#define RH_SET_ADDRESS          0x0500
+#define RH_GET_DESCRIPTOR       0x0680
+#define RH_SET_DESCRIPTOR       0x0700
+#define RH_GET_CONFIGURATION    0x0880
+#define RH_SET_CONFIGURATION    0x0900
+#define RH_GET_STATE            0x0280
+#define RH_GET_INTERFACE        0x0A80
+#define RH_SET_INTERFACE        0x0B00
+#define RH_SYNC_FRAME           0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP               0x2000
+
+/* Hub port features */
+#define RH_PORT_CONNECTION         0x00
+#define RH_PORT_ENABLE             0x01
+#define RH_PORT_SUSPEND            0x02
+#define RH_PORT_OVER_CURRENT       0x03
+#define RH_PORT_RESET              0x04
+#define RH_PORT_POWER              0x08
+#define RH_PORT_LOW_SPEED          0x09
+
+#define RH_C_PORT_CONNECTION       0x10
+#define RH_C_PORT_ENABLE           0x11
+#define RH_C_PORT_SUSPEND          0x12
+#define RH_C_PORT_OVER_CURRENT     0x13
+#define RH_C_PORT_RESET            0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER       0x00
+#define RH_C_HUB_OVER_CURRENT      0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP    0x00
+#define RH_ENDPOINT_STALL          0x01
+
+#define RH_ACK                     0x01
+#define RH_REQ_ERR                 -1
+#define RH_NACK                    0x00
diff --git a/drivers/nand/nand_util.c b/drivers/nand/nand_util.c
index 88c1df6c20b8601a458518fc5e55ba06ff8a882a..aee8727039083a43d6d411b66a27075a32fb69cf 100644
--- a/drivers/nand/nand_util.c
+++ b/drivers/nand/nand_util.c
@@ -37,6 +37,7 @@
 #include <command.h>
 #include <watchdog.h>
 #include <malloc.h>
+#include <div64.h>
 
 #include <nand.h>
 #include <jffs2/jffs2.h>
@@ -208,10 +209,10 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
 		}
 
 		if (!opts->quiet) {
-			int percent = (int)
-				((unsigned long long)
+                        unsigned long long n =(unsigned long long)
 				 (erase.addr+meminfo->erasesize-opts->offset)
-				 * 100 / erase_length);
+				 * 100;
+			int percent = (int)do_div(n, erase_length);
 
 			/* output progress message only at whole percent
 			 * steps to reduce the number of messages printed
@@ -475,10 +476,9 @@ int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts)
 		imglen -= readlen;
 
 		if (!opts->quiet) {
-			int percent = (int)
-				((unsigned long long)
-				 (opts->length-imglen) * 100
-				 / opts->length);
+                        unsigned long long n = (unsigned long long)
+			         (opts->length-imglen) * 100;
+			int percent = (int)do_div(n, opts->length);
 			/* output progress message only at whole percent
 			 * steps to reduce the number of messages printed
 			 * on (slow) serial consoles
@@ -651,10 +651,9 @@ int nand_read_opts(nand_info_t *meminfo, const nand_read_options_t *opts)
 		}
 
 		if (!opts->quiet) {
-			int percent = (int)
-				((unsigned long long)
-				 (opts->length-imglen) * 100
-				 / opts->length);
+                        unsigned long long n = (unsigned long long)
+			         (opts->length-imglen) * 100;
+			int percent = (int)do_div(n ,opts->length);
 			/* output progress message only at whole percent
 			 * steps to reduce the number of messages printed
 			 * on (slow) serial consoles
diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c
index 5f209629f40e4c0d82aa9f1b71e7dd7e7f114c62..0f5232a72afe4d394e1526276873adcb2a9891a5 100644
--- a/drivers/qe/qe.c
+++ b/drivers/qe/qe.c
@@ -98,7 +98,7 @@ static void qe_sdma_init(void)
 	out_be32(&p->sdaqmr, 0);
 
 	/* Allocate 2KB temporary buffer for sdma */
-	sdma_buffer_base = qe_muram_alloc(2048, 64);
+	sdma_buffer_base = qe_muram_alloc(2048, 4096);
 	out_be32(&p->sdwbcr, sdma_buffer_base & QE_SDEBCR_BA_MASK);
 
 	/* Clear sdma status */
diff --git a/drivers/qe/qe.h b/drivers/qe/qe.h
index 0bcd0a9573e8941515c3deeee68d97dd8b448229..400b1a6f603839444483f7f13c0022939277da08 100644
--- a/drivers/qe/qe.h
+++ b/drivers/qe/qe.h
@@ -29,7 +29,7 @@
 #define QE_NUM_OF_BRGS	16
 #define UCC_MAX_NUM	8
 
-#define QE_DATAONLY_BASE	(uint)(128)
+#define QE_DATAONLY_BASE	0
 #define QE_DATAONLY_SIZE	(QE_MURAM_SIZE - QE_DATAONLY_BASE)
 
 /* QE threads SNUM
diff --git a/drivers/tsec.c b/drivers/tsec.c
index 60bef9af39472c4fc4a6623a7070845ba698afd4..c0111234940fbc58159927342e2ed4fcf21587dd 100644
--- a/drivers/tsec.c
+++ b/drivers/tsec.c
@@ -71,6 +71,7 @@ static struct tsec_info_struct tsec_info[] = {
 #else
 	{TSEC1_PHY_ADDR, TSEC_GIGABIT, TSEC1_PHYIDX},
 #endif
+#else
 	{0, 0, 0},
 #endif
 #if defined(CONFIG_TSEC2)
@@ -79,6 +80,7 @@ static struct tsec_info_struct tsec_info[] = {
 #else
 	{TSEC2_PHY_ADDR, TSEC_GIGABIT, TSEC2_PHYIDX},
 #endif
+#else
 	{0, 0, 0},
 #endif
 #ifdef CONFIG_MPC85XX_FEC
@@ -296,9 +298,9 @@ static int init_phy(struct eth_device *dev)
 	volatile tsec_t *regs = (volatile tsec_t *)(TSEC_BASE_ADDR);
 
 	/* Assign a Physical address to the TBI */
-	regs->tbipa = TBIPA_VALUE;
+	regs->tbipa = CFG_TBIPA_VALUE;
 	regs = (volatile tsec_t *)(TSEC_BASE_ADDR + TSEC_SIZE);
-	regs->tbipa = TBIPA_VALUE;
+	regs->tbipa = CFG_TBIPA_VALUE;
 	asm("sync");
 
 	/* Reset MII (due to new addresses) */
diff --git a/drivers/tsec.h b/drivers/tsec.h
index 7bf3dee2b6859ae67860c0b12a69ab1791ccfea3..2f0092ad59888d6502ca245a0da5634b940f558d 100644
--- a/drivers/tsec.h
+++ b/drivers/tsec.h
@@ -70,7 +70,9 @@
 #define miim_end -2
 #define miim_read -1
 
-#define TBIPA_VALUE		0x1f
+#ifndef CFG_TBIPA_VALUE
+    #define CFG_TBIPA_VALUE	0x1f
+#endif
 #define MIIMCFG_INIT_VALUE	0x00000003
 #define MIIMCFG_RESET		0x80000000
 
diff --git a/cpu/arm920t/at91rm9200/usb_ohci.c b/drivers/usb_ohci.c
similarity index 76%
rename from cpu/arm920t/at91rm9200/usb_ohci.c
rename to drivers/usb_ohci.c
index 5b2c56cffc427ee40d4812a0d9119f2e178c3a79..d6b745fadd65f09217fbf1d3ede23e51bcba43d9 100644
--- a/cpu/arm920t/at91rm9200/usb_ohci.c
+++ b/drivers/usb_ohci.c
@@ -1,5 +1,11 @@
 /*
- * URB OHCI HCD (Host Controller Driver) for USB on the AT91RM9200.
+ * URB OHCI HCD (Host Controller Driver) for USB on the AT91RM9200 and PCI bus.
+ *
+ * Interrupt support is added. Now, it has been tested
+ * on ULI1575 chip and works well with USB keyboard.
+ *
+ * (C) Copyright 2007
+ * Zhang Wei, Freescale Semiconductor, Inc. <wei.zhang@freescale.com>
  *
  * (C) Copyright 2003
  * Gary Jennejohn, DENX Software Engineering <gj@denx.de>
@@ -21,7 +27,7 @@
  *
  * 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
+ * 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
@@ -32,38 +38,66 @@
  */
 /*
  * IMPORTANT NOTES
- * 1 - you MUST define LITTLEENDIAN in the configuration file for the
- *     board or this driver will NOT work!
+ * 1 - Read doc/README.generic_usb_ohci
  * 2 - this driver is intended for use with USB Mass Storage Devices
- *     (BBB) ONLY. There is NO support for Interrupt or Isochronous pipes!
- * 3 - when running on a PQFP208 AT91RM9200, define CONFIG_AT91C_PQFP_UHPBUG
+ *     (BBB) and USB keyboard. There is NO support for Isochronous pipes!
+ * 2 - when running on a PQFP208 AT91RM9200, define CONFIG_AT91C_PQFP_UHPBUG
  *     to activate workaround for bug #41 or this driver will NOT work!
  */
 
 #include <common.h>
-/* #include <pci.h> no PCI on the S3C24X0 */
 
-#ifdef CONFIG_USB_OHCI
+#ifdef CONFIG_USB_OHCI_NEW
 
-#include <asm/arch/hardware.h>
+#include <asm/byteorder.h>
+
+#if defined(CONFIG_PCI_OHCI)
+# include <pci.h>
+#endif
 
 #include <malloc.h>
 #include <usb.h>
 #include "usb_ohci.h"
 
-#define OHCI_USE_NPS		/* force NoPowerSwitching mode */
+#if defined(CONFIG_ARM920T) || \
+    defined(CONFIG_S3C2400) || \
+    defined(CONFIG_S3C2410) || \
+    defined(CONFIG_440EP) || \
+    defined(CONFIG_PCI_OHCI) || \
+    defined(CONFIG_MPC5200)
+# define OHCI_USE_NPS		/* force NoPowerSwitching mode */
+#endif
+
 #undef OHCI_VERBOSE_DEBUG	/* not always helpful */
+#undef DEBUG
+#undef SHOW_INFO
+#undef OHCI_FILL_TRACE
 
 /* For initializing controller (mask in an HCFS mode too) */
 #define OHCI_CONTROL_INIT \
 	(OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
 
-#define readl(a) (*((vu_long *)(a)))
-#define writel(a, b) (*((vu_long *)(b)) = ((vu_long)a))
+/*
+ * e.g. PCI controllers need this
+ */
+#ifdef CFG_OHCI_SWAP_REG_ACCESS
+# define readl(a) __swap_32(*((vu_long *)(a)))
+# define writel(a, b) (*((vu_long *)(b)) = __swap_32((vu_long)a))
+#else
+# define readl(a) (*((vu_long *)(a)))
+# define writel(a, b) (*((vu_long *)(b)) = ((vu_long)a))
+#endif /* CFG_OHCI_SWAP_REG_ACCESS */
 
 #define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
 
-#undef DEBUG
+#ifdef CONFIG_PCI_OHCI
+static struct pci_device_id ohci_pci_ids[] = {
+	{0x10b9, 0x5237},	/* ULI1575 PCI OHCI module ids */
+	/* Please add supported PCI OHCI controller ids here */
+	{0, 0}
+};
+#endif
+
 #ifdef DEBUG
 #define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)
 #else
@@ -77,8 +111,13 @@
 #define info(format, arg...) do {} while(0)
 #endif
 
-#define m16_swap(x) swap_16(x)
-#define m32_swap(x) swap_32(x)
+#ifdef CFG_OHCI_BE_CONTROLLER
+# define m16_swap(x) cpu_to_be16(x)
+# define m32_swap(x) cpu_to_be32(x)
+#else
+# define m16_swap(x) cpu_to_le16(x)
+# define m32_swap(x) cpu_to_le32(x)
+#endif /* CFG_OHCI_BE_CONTROLLER */
 
 /* global ohci_t */
 static ohci_t gohci;
@@ -88,13 +127,13 @@ struct ohci_hcca ghcca[1];
 struct ohci_hcca *phcca;
 /* this allocates EDs for all possible endpoints */
 struct ohci_device ohci_dev;
-/* urb_priv */
-urb_priv_t urb_priv;
 /* RHSC flag */
 int got_rhsc;
 /* device which was disconnected */
 struct usb_device *devgone;
 
+
+
 /*-------------------------------------------------------------------------*/
 
 /* AMD-756 (D2 rev) reports corrupt register contents in some cases.
@@ -147,6 +186,7 @@ static void urb_free_priv (urb_priv_t * urb)
 			}
 		}
 	}
+	free(urb);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -157,11 +197,10 @@ static int sohci_get_current_frame_number (struct usb_device * dev);
 /* debug| print the main components of an URB
  * small: 0) header + data packets 1) just header */
 
-static void pkt_print (struct usb_device * dev, unsigned long pipe, void * buffer,
+static void pkt_print (urb_priv_t *purb, struct usb_device * dev,
+	unsigned long pipe, void * buffer,
 	int transfer_len, struct devrequest * setup, char * str, int small)
 {
-	urb_priv_t * purb = &urb_priv;
-
 	dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx",
 			str,
 			sohci_get_current_frame_number (dev),
@@ -170,7 +209,7 @@ static void pkt_print (struct usb_device * dev, unsigned long pipe, void * buffe
 			usb_pipeout (pipe)? 'O': 'I',
 			usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
 				(usb_pipecontrol (pipe)? "CTRL": "BULK"),
-			purb->actual_length,
+			(purb ? purb->actual_length : 0),
 			transfer_len, dev->status);
 #ifdef	OHCI_VERBOSE_DEBUG
 	if (!small) {
@@ -184,10 +223,11 @@ static void pkt_print (struct usb_device * dev, unsigned long pipe, void * buffe
 		}
 		if (transfer_len > 0 && buffer) {
 			printf (__FILE__ ": data(%d/%d):",
-				purb->actual_length,
+				(purb ? purb->actual_length : 0),
 				transfer_len);
 			len = usb_pipeout (pipe)?
-					transfer_len: purb->actual_length;
+					transfer_len:
+					(purb ? purb->actual_length : 0);
 			for (i = 0; i < 16 && i < len; i++)
 				printf (" %02x", ((__u8 *) buffer) [i]);
 			printf ("%s\n", i < len? "...": "");
@@ -383,13 +423,17 @@ static void ohci_dump (ohci_t *controller, int verbose)
 
 /* get a transfer request */
 
-int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
-		int transfer_len, struct devrequest *setup, int interval)
+int sohci_submit_job(urb_priv_t *urb, struct devrequest *setup)
 {
 	ohci_t *ohci;
 	ed_t * ed;
-	urb_priv_t *purb_priv;
+	urb_priv_t *purb_priv = urb;
 	int i, size = 0;
+	struct usb_device *dev = urb->dev;
+	unsigned long pipe = urb->pipe;
+	void *buffer = urb->transfer_buffer;
+	int transfer_len = urb->transfer_buffer_length;
+	int interval = urb->interval;
 
 	ohci = &gohci;
 
@@ -400,8 +444,11 @@ int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
 		return -1;
 	}
 
+	/* we're about to begin a new transaction here so mark the URB unfinished */
+	urb->finished = 0;
+
 	/* every endpoint has a ed, locate and fill it */
-	if (!(ed = ep_add_ed (dev, pipe))) {
+	if (!(ed = ep_add_ed (dev, pipe, interval, 1))) {
 		err("sohci_submit_job: ENOMEM");
 		return -1;
 	}
@@ -415,13 +462,17 @@ int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
 			size = (transfer_len == 0)? 2:
 						(transfer_len - 1) / 4096 + 3;
 			break;
+		case PIPE_INTERRUPT: /* 1 TD */
+			size = 1;
+			break;
 	}
 
+	ed->purb = urb;
+
 	if (size >= (N_URB_TD - 1)) {
 		err("need %d TDs, only have %d", size, N_URB_TD);
 		return -1;
 	}
-	purb_priv = &urb_priv;
 	purb_priv->pipe = pipe;
 
 	/* fill the private part of the URB */
@@ -457,6 +508,40 @@ int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
 	return 0;
 }
 
+static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb)
+{
+	struct ohci_regs *regs = hc->regs;
+
+	switch (usb_pipetype (urb->pipe)) {
+	case PIPE_INTERRUPT:
+		/* implicitly requeued */
+		if (urb->dev->irq_handle &&
+				(urb->dev->irq_act_len = urb->actual_length)) {
+			writel (OHCI_INTR_WDH, &regs->intrenable);
+			readl (&regs->intrenable); /* PCI posting flush */
+			urb->dev->irq_handle(urb->dev);
+			writel (OHCI_INTR_WDH, &regs->intrdisable);
+			readl (&regs->intrdisable); /* PCI posting flush */
+		}
+		urb->actual_length = 0;
+		td_submit_job (
+				urb->dev,
+				urb->pipe,
+				urb->transfer_buffer,
+				urb->transfer_buffer_length,
+				NULL,
+				urb,
+				urb->interval);
+		break;
+	case PIPE_CONTROL:
+	case PIPE_BULK:
+		break;
+	default:
+		return 0;
+	}
+	return 1;
+}
+
 /*-------------------------------------------------------------------------*/
 
 #ifdef DEBUG
@@ -470,6 +555,59 @@ static int sohci_get_current_frame_number (struct usb_device *usb_dev)
 }
 #endif
 
+/*-------------------------------------------------------------------------*
+ * ED handling functions
+ *-------------------------------------------------------------------------*/
+
+/* search for the right branch to insert an interrupt ed into the int tree
+ * do some load ballancing;
+ * returns the branch and
+ * sets the interval to interval = 2^integer (ld (interval)) */
+
+static int ep_int_ballance (ohci_t * ohci, int interval, int load)
+{
+	int i, branch = 0;
+
+	/* search for the least loaded interrupt endpoint
+	 * branch of all 32 branches
+	 */
+	for (i = 0; i < 32; i++)
+		if (ohci->ohci_int_load [branch] > ohci->ohci_int_load [i])
+			branch = i;
+
+	branch = branch % interval;
+	for (i = branch; i < 32; i += interval)
+		ohci->ohci_int_load [i] += load;
+
+	return branch;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*  2^int( ld (inter)) */
+
+static int ep_2_n_interval (int inter)
+{
+	int i;
+	for (i = 0; ((inter >> i) > 1 ) && (i < 5); i++);
+	return 1 << i;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* the int tree is a binary tree
+ * in order to process it sequentially the indexes of the branches have to be mapped
+ * the mapping reverses the bits of a word of num_bits length */
+
+static int ep_rev (int num_bits, int word)
+{
+	int i, wout = 0;
+
+	for (i = 0; i < num_bits; i++)
+		wout |= (((word >> i) & 1) << (num_bits - i - 1));
+	return wout;
+}
+
 /*-------------------------------------------------------------------------*
  * ED handling functions
  *-------------------------------------------------------------------------*/
@@ -479,8 +617,15 @@ static int sohci_get_current_frame_number (struct usb_device *usb_dev)
 static int ep_link (ohci_t *ohci, ed_t *edi)
 {
 	volatile ed_t *ed = edi;
+	int int_branch;
+	int i;
+	int inter;
+	int interval;
+	int load;
+	__u32 * ed_p;
 
 	ed->state = ED_OPER;
+	ed->int_interval = 0;
 
 	switch (ed->type) {
 	case PIPE_CONTROL:
@@ -488,7 +633,7 @@ static int ep_link (ohci_t *ohci, ed_t *edi)
 		if (ohci->ed_controltail == NULL) {
 			writel (ed, &ohci->regs->ed_controlhead);
 		} else {
-			ohci->ed_controltail->hwNextED = m32_swap (ed);
+			ohci->ed_controltail->hwNextED = m32_swap ((unsigned long)ed);
 		}
 		ed->ed_prev = ohci->ed_controltail;
 		if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
@@ -504,7 +649,7 @@ static int ep_link (ohci_t *ohci, ed_t *edi)
 		if (ohci->ed_bulktail == NULL) {
 			writel (ed, &ohci->regs->ed_bulkhead);
 		} else {
-			ohci->ed_bulktail->hwNextED = m32_swap (ed);
+			ohci->ed_bulktail->hwNextED = m32_swap ((unsigned long)ed);
 		}
 		ed->ed_prev = ohci->ed_bulktail;
 		if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
@@ -514,19 +659,59 @@ static int ep_link (ohci_t *ohci, ed_t *edi)
 		}
 		ohci->ed_bulktail = edi;
 		break;
+
+	case PIPE_INTERRUPT:
+		load = ed->int_load;
+		interval = ep_2_n_interval (ed->int_period);
+		ed->int_interval = interval;
+		int_branch = ep_int_ballance (ohci, interval, load);
+		ed->int_branch = int_branch;
+
+		for (i = 0; i < ep_rev (6, interval); i += inter) {
+			inter = 1;
+			for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i) + int_branch]);
+				(*ed_p != 0) && (((ed_t *)ed_p)->int_interval >= interval);
+				ed_p = &(((ed_t *)ed_p)->hwNextED))
+					inter = ep_rev (6, ((ed_t *)ed_p)->int_interval);
+			ed->hwNextED = *ed_p;
+			*ed_p = m32_swap(ed);
+		}
+		break;
 	}
 	return 0;
 }
 
 /*-------------------------------------------------------------------------*/
 
+/* scan the periodic table to find and unlink this ED */
+static void periodic_unlink ( struct ohci *ohci, volatile struct ed *ed,
+		unsigned index, unsigned period)
+{
+	for (; index < NUM_INTS; index += period) {
+		__u32	*ed_p = &ohci->hcca->int_table [index];
+
+		/* ED might have been unlinked through another path */
+		while (*ed_p != 0) {
+			if (((struct ed *)m32_swap (ed_p)) == ed) {
+				*ed_p = ed->hwNextED;
+				break;
+			}
+			ed_p = & (((struct ed *)m32_swap (ed_p))->hwNextED);
+		}
+	}
+}
+
+
 /* unlink an ed from one of the HC chains.
  * just the link to the ed is unlinked.
  * the link from the ed still points to another operational ed or 0
  * so the HC can eventually finish the processing of the unlinked ed */
 
-static int ep_unlink (ohci_t *ohci, ed_t *ed)
+static int ep_unlink (ohci_t *ohci, ed_t *edi)
 {
+	volatile ed_t *ed = edi;
+	int i;
+
 	ed->hwINFO |= m32_swap (OHCI_ED_SKIP);
 
 	switch (ed->type) {
@@ -563,6 +748,12 @@ static int ep_unlink (ohci_t *ohci, ed_t *ed)
 			((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
 		}
 		break;
+
+	case PIPE_INTERRUPT:
+		periodic_unlink (ohci, ed, 0, 1);
+		for (i = ed->int_branch; i < 32; i += ed->int_interval)
+		    ohci->ohci_int_load[i] -= ed->int_load;
+		break;
 	}
 	ed->state = ED_UNLINK;
 	return 0;
@@ -571,13 +762,16 @@ static int ep_unlink (ohci_t *ohci, ed_t *ed)
 
 /*-------------------------------------------------------------------------*/
 
-/* add/reinit an endpoint; this should be done once at the usb_set_configuration command,
- * but the USB stack is a little bit stateless	so we do it at every transaction
- * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK
- * in all other cases the state is left unchanged
- * the ed info fields are setted anyway even though most of them should not change */
-
-static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
+/* add/reinit an endpoint; this should be done once at the
+ * usb_set_configuration command, but the USB stack is a little bit
+ * stateless so we do it at every transaction if the state of the ed
+ * is ED_NEW then a dummy td is added and the state is changed to
+ * ED_UNLINK in all other cases the state is left unchanged the ed
+ * info fields are setted anyway even though most of them should not
+ * change
+ */
+static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe,
+		int interval, int load)
 {
 	td_t *td;
 	ed_t *ed_ret;
@@ -596,7 +790,7 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
 		ed->hwINFO = m32_swap (OHCI_ED_SKIP); /* skip ed */
 		/* dummy td; end of td list for ed */
 		td = td_alloc (usb_dev);
-		ed->hwTailP = m32_swap (td);
+		ed->hwTailP = m32_swap ((unsigned long)td);
 		ed->hwHeadP = ed->hwTailP;
 		ed->state = ED_UNLINK;
 		ed->type = usb_pipetype (pipe);
@@ -610,6 +804,11 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
 			| usb_pipeslow (pipe) << 13
 			| usb_maxpacket (usb_dev, pipe) << 16);
 
+	if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) {
+		ed->int_period = interval;
+		ed->int_load = load;
+	}
+
 	return ed_ret;
 }
 
@@ -654,13 +853,12 @@ static void td_fill (ohci_t *ohci, unsigned int info,
 		data = 0;
 
 	td->hwINFO = m32_swap (info);
-	td->hwCBP = m32_swap (data);
+	td->hwCBP = m32_swap ((unsigned long)data);
 	if (data)
-		td->hwBE = m32_swap (data + len - 1);
+		td->hwBE = m32_swap ((unsigned long)(data + len - 1));
 	else
 		td->hwBE = 0;
-	td->hwNextTD = m32_swap (td_pt);
-	td->hwPSW [0] = m16_swap (((__u32)data & 0x0FFF) | 0xE000);
+	td->hwNextTD = m32_swap ((unsigned long)td_pt);
 
 	/* append to queue */
 	td->ed->hwTailP = td->hwNextTD;
@@ -725,6 +923,13 @@ static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buf
 		if (!ohci->sleeping)
 			writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
 		break;
+
+	case PIPE_INTERRUPT:
+		info = usb_pipeout (urb->pipe)?
+			TD_CC | TD_DP_OUT | toggle:
+			TD_CC | TD_R | TD_DP_IN | toggle;
+		td_fill (ohci, info, data, data_len, dev, cnt++, urb);
+		break;
 	}
 	if (urb->length != cnt)
 		dbg("TD LENGTH %d != CNT %d", urb->length, cnt);
@@ -740,7 +945,7 @@ static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buf
 static void dl_transfer_length(td_t * td)
 {
 	__u32 tdINFO, tdBE, tdCBP;
-	urb_priv_t *lurb_priv = &urb_priv;
+	urb_priv_t *lurb_priv = td->ed->purb;
 
 	tdINFO = m32_swap (td->hwINFO);
 	tdBE   = m32_swap (td->hwBE);
@@ -777,7 +982,7 @@ static td_t * dl_reverse_done_list (ohci_t *ohci)
 		td_list = (td_t *)td_list_hc;
 
 		if (TD_CC_GET (m32_swap (td_list->hwINFO))) {
-			lurb_priv = &urb_priv;
+			lurb_priv = td_list->ed->purb;
 			dbg(" USB-error/status: %x : %p",
 					TD_CC_GET (m32_swap (td_list->hwINFO)), td_list);
 			if (td_list->ed->hwHeadP & m32_swap (0x1)) {
@@ -789,6 +994,9 @@ static td_t * dl_reverse_done_list (ohci_t *ohci)
 				} else
 					td_list->ed->hwHeadP &= m32_swap (0xfffffff2);
 			}
+#ifdef CONFIG_MPC5200
+			td_list->hwNextTD = 0;
+#endif
 		}
 
 		td_list->next_dl_td = td_rev;
@@ -814,10 +1022,10 @@ static int dl_done_list (ohci_t *ohci, td_t *td_list)
 	while (td_list) {
 		td_list_next = td_list->next_dl_td;
 
-		lurb_priv = &urb_priv;
 		tdINFO = m32_swap (td_list->hwINFO);
 
 		ed = td_list->ed;
+		lurb_priv = ed->purb;
 
 		dl_transfer_length(td_list);
 
@@ -828,7 +1036,24 @@ static int dl_done_list (ohci_t *ohci, td_t *td_list)
 			stat = cc_to_error[cc];
 		}
 
-		if (ed->state != ED_NEW) {
+		/* see if this done list makes for all TD's of current URB,
+		 * and mark the URB finished if so */
+		if (++(lurb_priv->td_cnt) == lurb_priv->length) {
+#if 1
+			if ((ed->state & (ED_OPER | ED_UNLINK)) &&
+			    (lurb_priv->state != URB_DEL))
+#else
+			if ((ed->state & (ED_OPER | ED_UNLINK)))
+#endif
+				lurb_priv->finished = sohci_return_job(ohci,
+						lurb_priv);
+			else
+				dbg("dl_done_list: strange.., ED state %x, ed->state\n");
+		} else
+			dbg("dl_done_list: processing TD %x, len %x\n", lurb_priv->td_cnt,
+				lurb_priv->length);
+		if (ed->state != ED_NEW &&
+			  (usb_pipetype (lurb_priv->pipe) != PIPE_INTERRUPT)) {
 			edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0;
 			edTailP = m32_swap (ed->hwTailP);
 
@@ -974,7 +1199,6 @@ int rh_check_port_status(ohci_t *controller)
 #ifdef CONFIG_AT91C_PQFP_UHPBUG
 	ndp = (ndp == 2) ? 1:0;
 #endif
-
 	for (i = 0; i < ndp; i++) {
 		temp = roothub_portstatus (controller, i);
 		/* check for a device disconnect */
@@ -1003,8 +1227,7 @@ static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
 	__u16 wLength;
 
 #ifdef DEBUG
-urb_priv.actual_length = 0;
-pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
+pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
 #else
 	wait_ms(1);
 #endif
@@ -1014,9 +1237,9 @@ pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
 	}
 
 	bmRType_bReq  = cmd->requesttype | (cmd->request << 8);
-	wValue	      = m16_swap (cmd->value);
-	wIndex	      = m16_swap (cmd->index);
-	wLength	      = m16_swap (cmd->length);
+	wValue	      = cpu_to_le16 (cmd->value);
+	wIndex	      = cpu_to_le16 (cmd->index);
+	wLength	      = cpu_to_le16 (cmd->length);
 
 	info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x",
 		dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
@@ -1031,17 +1254,17 @@ pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
 	*/
 
 	case RH_GET_STATUS:
-			*(__u16 *) data_buf = m16_swap (1); OK (2);
+			*(__u16 *) data_buf = cpu_to_le16 (1); OK (2);
 	case RH_GET_STATUS | RH_INTERFACE:
-			*(__u16 *) data_buf = m16_swap (0); OK (2);
+			*(__u16 *) data_buf = cpu_to_le16 (0); OK (2);
 	case RH_GET_STATUS | RH_ENDPOINT:
-			*(__u16 *) data_buf = m16_swap (0); OK (2);
+			*(__u16 *) data_buf = cpu_to_le16 (0); OK (2);
 	case RH_GET_STATUS | RH_CLASS:
-			*(__u32 *) data_buf = m32_swap (
+			*(__u32 *) data_buf = cpu_to_le32 (
 				RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
 			OK (4);
 	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
-			*(__u32 *) data_buf = m32_swap (RD_RH_PORTSTAT); OK (4);
+			*(__u32 *) data_buf = cpu_to_le32 (RD_RH_PORTSTAT); OK (4);
 
 	case RH_CLEAR_FEATURE | RH_ENDPOINT:
 		switch (wValue) {
@@ -1088,7 +1311,9 @@ pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
 					    WR_RH_PORTSTAT (RH_PS_PRS);
 					OK (0);
 			case (RH_PORT_POWER):
-					WR_RH_PORTSTAT (RH_PS_PPS ); OK (0);
+					WR_RH_PORTSTAT (RH_PS_PPS );
+					wait_ms(100);
+					OK (0);
 			case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/
 					if (RD_RH_PORTSTAT & RH_PS_CCS)
 					    WR_RH_PORTSTAT (RH_PS_PES );
@@ -1170,7 +1395,7 @@ pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
 		}
 
 		len = min_t(unsigned int, leni,
-		min_t(unsigned int, data_buf [0], wLength));
+			    min_t(unsigned int, data_buf [0], wLength));
 		OK (len);
 	}
 
@@ -1196,9 +1421,7 @@ pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
 	dev->status = stat;
 
 #ifdef DEBUG
-	if (transfer_len)
-		urb_priv.actual_length = transfer_len;
-	pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);
+	pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);
 #else
 	wait_ms(1);
 #endif
@@ -1216,6 +1439,16 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 	int stat = 0;
 	int maxsize = usb_maxpacket(dev, pipe);
 	int timeout;
+	urb_priv_t *urb;
+
+	urb = malloc(sizeof(urb_priv_t));
+	memset(urb, 0, sizeof(urb_priv_t));
+
+	urb->dev = dev;
+	urb->pipe = pipe;
+	urb->transfer_buffer = buffer;
+	urb->transfer_buffer_length = transfer_len;
+	urb->interval = interval;
 
 	/* device pulled? Shortcut the action. */
 	if (devgone == dev) {
@@ -1224,8 +1457,8 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 	}
 
 #ifdef DEBUG
-	urb_priv.actual_length = 0;
-	pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
+	urb->actual_length = 0;
+	pkt_print(urb, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
 #else
 	wait_ms(1);
 #endif
@@ -1235,13 +1468,15 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 		return -1;
 	}
 
-	if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) < 0) {
+	if (sohci_submit_job(urb, setup) < 0) {
 		err("sohci_submit_job failed");
 		return -1;
 	}
 
+#if 0
 	wait_ms(10);
 	/* ohci_dump_status(&gohci); */
+#endif
 
 	/* allow more time for a BULK device to react - some are slow */
 #define BULK_TO	 5000	/* timeout in milliseconds */
@@ -1258,51 +1493,47 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 			stat = USB_ST_CRC_ERR;
 			break;
 		}
-		if (stat >= 0 && stat != 0xff) {
+
+		/* NOTE: since we are not interrupt driven in U-Boot and always
+		 * handle only one URB at a time, we cannot assume the
+		 * transaction finished on the first successful return from
+		 * hc_interrupt().. unless the flag for current URB is set,
+		 * meaning that all TD's to/from device got actually
+		 * transferred and processed. If the current URB is not
+		 * finished we need to re-iterate this loop so as
+		 * hc_interrupt() gets called again as there needs to be some
+		 * more TD's to process still */
+		if ((stat >= 0) && (stat != 0xff) && (urb->finished)) {
 			/* 0xff is returned for an SF-interrupt */
 			break;
 		}
+
 		if (--timeout) {
 			wait_ms(1);
+			if (!urb->finished)
+				dbg("\%");
+
 		} else {
 			err("CTL:TIMEOUT ");
+			dbg("submit_common_msg: TO status %x\n", stat);
+			urb->finished = 1;
 			stat = USB_ST_CRC_ERR;
 			break;
 		}
 	}
-	/* we got an Root Hub Status Change interrupt */
-	if (got_rhsc) {
-#ifdef DEBUG
-		ohci_dump_roothub (&gohci, 1);
-#endif
-		got_rhsc = 0;
-		/* abuse timeout */
-		timeout = rh_check_port_status(&gohci);
-		if (timeout >= 0) {
-#if 0 /* this does nothing useful, but leave it here in case that changes */
-			/* the called routine adds 1 to the passed value */
-			usb_hub_port_connect_change(gohci.rh.dev, timeout - 1);
-#endif
-			/*
-			 * XXX
-			 * This is potentially dangerous because it assumes
-			 * that only one device is ever plugged in!
-			 */
-			devgone = dev;
-		}
-	}
 
 	dev->status = stat;
 	dev->act_len = transfer_len;
 
 #ifdef DEBUG
-	pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe));
+	pkt_print(urb, dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe));
 #else
 	wait_ms(1);
 #endif
 
 	/* free TDs in urb_priv */
-	urb_free_priv (&urb_priv);
+	if (usb_pipetype (pipe) != PIPE_INTERRUPT)
+		urb_free_priv (urb);
 	return 0;
 }
 
@@ -1321,8 +1552,7 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 
 	info("submit_control_msg");
 #ifdef DEBUG
-	urb_priv.actual_length = 0;
-	pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
+	pkt_print(NULL, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
 #else
 	wait_ms(1);
 #endif
@@ -1345,7 +1575,8 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 		int transfer_len, int interval)
 {
 	info("submit_int_msg");
-	return -1;
+	return submit_common_msg(dev, pipe, buffer, transfer_len, NULL,
+			interval);
 }
 
 /*-------------------------------------------------------------------------*
@@ -1381,7 +1612,8 @@ static int hc_reset (ohci_t *ohci)
 		readl(&ohci->regs->control));
 
 	/* Reset USB (needed by some controllers) */
-	writel (0, &ohci->regs->control);
+	ohci->hc_control = 0;
+	writel (ohci->hc_control, &ohci->regs->control);
 
 	/* HC Reset requires max 10 us delay */
 	writel (OHCI_HCR,  &ohci->regs->cmdstatus);
@@ -1458,26 +1690,38 @@ static int hc_start (ohci_t * ohci)
 
 /*-------------------------------------------------------------------------*/
 
+/* Poll USB interrupt. */
+void usb_event_poll(void)
+{
+	hc_interrupt();
+}
+
 /* an interrupt happens */
 
-static int
-hc_interrupt (void)
+static int hc_interrupt (void)
 {
 	ohci_t *ohci = &gohci;
 	struct ohci_regs *regs = ohci->regs;
 	int ints;
 	int stat = -1;
 
-	if ((ohci->hcca->done_head != 0) && !(m32_swap (ohci->hcca->done_head) & 0x01)) {
-		ints =	OHCI_INTR_WDH;
-	} else {
-		ints = readl (&regs->intrstatus);
+	if ((ohci->hcca->done_head != 0) &&
+	    !(m32_swap (ohci->hcca->done_head) & 0x01)) {
+		ints =  OHCI_INTR_WDH;
+	} else if ((ints = readl (&regs->intrstatus)) == ~(u32)0) {
+		ohci->disabled++;
+		err ("%s device removed!", ohci->slot_name);
+		return -1;
+	} else if ((ints &= readl (&regs->intrenable)) == 0) {
+		dbg("hc_interrupt: returning..\n");
+		return 0xff;
 	}
 
 	/* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */
 
 	if (ints & OHCI_INTR_RHSC) {
 		got_rhsc = 1;
+		stat = 0xff;
 	}
 
 	if (ints & OHCI_INTR_UE) {
@@ -1502,8 +1746,10 @@ hc_interrupt (void)
 	if (ints & OHCI_INTR_WDH) {
 		wait_ms(1);
 		writel (OHCI_INTR_WDH, &regs->intrdisable);
+		(void)readl (&regs->intrdisable); /* flush */
 		stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci));
 		writel (OHCI_INTR_WDH, &regs->intrenable);
+		(void)readl (&regs->intrdisable); /* flush */
 	}
 
 	if (ints & OHCI_INTR_SO) {
@@ -1549,14 +1795,22 @@ static char ohci_inited = 0;
 
 int usb_lowlevel_init(void)
 {
-	/*
-	 * Enable USB host clock.
-	 */
-	*AT91C_PMC_SCER = AT91C_PMC_UHP;	/* 48MHz clock enabled for UHP */
-	*AT91C_PMC_PCER = 1 << AT91C_ID_UHP;	/* Peripheral Clock Enable Register */
+#ifdef CONFIG_PCI_OHCI
+	pci_dev_t pdev;
+#endif
 
+#ifdef CFG_USB_OHCI_CPU_INIT
+	/* cpu dependant init */
+	if(usb_cpu_init())
+		return -1;
+#endif
+
+#ifdef CFG_USB_OHCI_BOARD_INIT
+	/*  board dependant init */
+	if(usb_board_init())
+		return -1;
+#endif
 	memset (&gohci, 0, sizeof (ohci_t));
-	memset (&urb_priv, 0, sizeof (urb_priv_t));
 
 	/* align the storage */
 	if ((__u32)&ghcca[0] & 0xff) {
@@ -1582,29 +1836,60 @@ int usb_lowlevel_init(void)
 	gohci.disabled = 1;
 	gohci.sleeping = 0;
 	gohci.irq = -1;
-	gohci.regs = (struct ohci_regs *)AT91_USB_HOST_BASE;
+#ifdef CONFIG_PCI_OHCI
+	pdev = pci_find_devices(ohci_pci_ids, 0);
+
+	if (pdev != -1) {
+		u16 vid, did;
+		u32 base;
+		pci_read_config_word(pdev, PCI_VENDOR_ID, &vid);
+		pci_read_config_word(pdev, PCI_DEVICE_ID, &did);
+		printf("OHCI pci controller (%04x, %04x) found @(%d:%d:%d)\n",
+				vid, did, (pdev >> 16) & 0xff,
+				(pdev >> 11) & 0x1f, (pdev >> 8) & 0x7);
+		pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &base);
+		printf("OHCI regs address 0x%08x\n", base);
+		gohci.regs = (struct ohci_regs *)base;
+	} else
+		return -1;
+#else
+	gohci.regs = (struct ohci_regs *)CFG_USB_OHCI_REGS_BASE;
+#endif
 
 	gohci.flags = 0;
-	gohci.slot_name = "at91rm9200";
+	gohci.slot_name = CFG_USB_OHCI_SLOT_NAME;
 
 	if (hc_reset (&gohci) < 0) {
 		hc_release_ohci (&gohci);
-		/* Initialization failed */
-		*AT91C_PMC_PCER = AT91C_ID_UHP;
-		*AT91C_PMC_SCDR = 1 << AT91C_PMC_UHP;	/* 48MHz clock disabled for UHP */
+		err ("can't reset usb-%s", gohci.slot_name);
+#ifdef CFG_USB_OHCI_BOARD_INIT
+		/* board dependant cleanup */
+		usb_board_init_fail();
+#endif
+
+#ifdef CFG_USB_OHCI_CPU_INIT
+		/* cpu dependant cleanup */
+		usb_cpu_init_fail();
+#endif
 		return -1;
 	}
 
 	/* FIXME this is a second HC reset; why?? */
-/*	writel (gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control);
-	wait_ms (10);*/
-
+	/* writel(gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control);
+	   wait_ms(10); */
 	if (hc_start (&gohci) < 0) {
 		err ("can't start usb-%s", gohci.slot_name);
 		hc_release_ohci (&gohci);
 		/* Initialization failed */
-		*AT91C_PMC_PCER = AT91C_ID_UHP;
-		*AT91C_PMC_SCDR = 1 << AT91C_PMC_UHP;	/* 48MHz clock disabled for UHP */
+#ifdef CFG_USB_OHCI_BOARD_INIT
+		/* board dependant cleanup */
+		usb_board_stop();
+#endif
+
+#ifdef CFG_USB_OHCI_CPU_INIT
+		/* cpu dependant cleanup */
+		usb_cpu_stop();
+#endif
 		return -1;
 	}
 
@@ -1626,10 +1911,19 @@ int usb_lowlevel_stop(void)
 	/* TODO release any interrupts, etc. */
 	/* call hc_release_ohci() here ? */
 	hc_reset (&gohci);
-	/* may not want to do this */
-	*AT91C_PMC_PCER = 1 << AT91C_ID_UHP;
-	*AT91C_PMC_SCDR = 1 << AT91C_PMC_UHP;	/* 48MHz clock disabled for UHP */
+
+#ifdef CFG_USB_OHCI_BOARD_INIT
+	/* board dependant cleanup */
+	if(usb_board_stop())
+		return -1;
+#endif
+
+#ifdef CFG_USB_OHCI_CPU_INIT
+	/* cpu dependant cleanup */
+	if(usb_cpu_stop())
+		return -1;
+#endif
+
 	return 0;
 }
-
-#endif /* CONFIG_USB_OHCI */
+#endif /* CONFIG_USB_OHCI_NEW */
diff --git a/cpu/arm920t/at91rm9200/usb_ohci.h b/drivers/usb_ohci.h
similarity index 92%
rename from cpu/arm920t/at91rm9200/usb_ohci.h
rename to drivers/usb_ohci.h
index ecb4e937b1801d899dfbc66a3fc3b8601f4f81eb..380cb4c92730b676c87038c0a0d6e889a1d29b6f 100644
--- a/cpu/arm920t/at91rm9200/usb_ohci.h
+++ b/drivers/usb_ohci.h
@@ -7,6 +7,15 @@
  * usb-ohci.h
  */
 
+/* functions for doing board or CPU specific setup/cleanup */
+extern int usb_board_init(void);
+extern int usb_board_stop(void);
+extern int usb_board_init_fail(void);
+
+extern int usb_cpu_init(void);
+extern int usb_cpu_stop(void);
+extern int usb_cpu_init_fail(void);
+
 
 static int cc_to_error[16] = {
 
@@ -55,7 +64,8 @@ struct ed {
 	struct ed *ed_rm_list;
 
 	struct usb_device *usb_dev;
-	__u32 unused[3];
+	void *purb;
+	__u32 unused[2];
 } __attribute((aligned(16)));
 typedef struct ed ed_t;
 
@@ -104,7 +114,9 @@ struct td {
 	__u32 hwNextTD;		/* Next TD Pointer */
 	__u32 hwBE;		/* Memory Buffer End Pointer */
 
+/* #ifndef CONFIG_MPC5200 /\* this seems wrong *\/ */
 	__u16 hwPSW[MAXPSW];
+/* #endif */
 	__u8 unused;
 	__u8 index;
 	struct ed *ed;
@@ -128,8 +140,13 @@ typedef struct td td_t;
 #define NUM_INTS 32	/* part of the OHCI standard */
 struct ohci_hcca {
 	__u32	int_table[NUM_INTS];	/* Interrupt ED table */
+#if defined(CONFIG_MPC5200)
+	__u16	pad1;			/* set to 0 on each frame_no change */
+	__u16	frame_no;		/* current frame number */
+#else
 	__u16	frame_no;		/* current frame number */
 	__u16	pad1;			/* set to 0 on each frame_no change */
+#endif
 	__u32	done_head;		/* info returned for an interrupt */
 	u8		reserved_for_hc[116];
 } __attribute((aligned(256)));
@@ -138,7 +155,9 @@ struct ohci_hcca {
 /*
  * Maximum number of root hub ports.
  */
-#define MAX_ROOT_PORTS	15	/* maximum OHCI root hub ports */
+#ifndef CFG_USB_OHCI_MAX_ROOT_PORTS
+# error "CFG_USB_OHCI_MAX_ROOT_PORTS undefined!"
+#endif
 
 /*
  * This is the structure of the OHCI controller's memory mapped I/O
@@ -172,7 +191,7 @@ struct ohci_regs {
 		__u32	a;
 		__u32	b;
 		__u32	status;
-		__u32	portstatus[MAX_ROOT_PORTS];
+		__u32	portstatus[CFG_USB_OHCI_MAX_ROOT_PORTS];
 	} roothub;
 } __attribute((aligned(32)));
 
@@ -331,9 +350,14 @@ typedef struct
 	ed_t *ed;
 	__u16 length;	/* number of tds associated with this request */
 	__u16 td_cnt;	/* number of tds already serviced */
+	struct usb_device *dev;
 	int   state;
 	unsigned long pipe;
+	void *transfer_buffer;
+	int transfer_buffer_length;
+	int interval;
 	int actual_length;
+	int finished;
 	td_t *td[N_URB_TD];	/* list pointer to all corresponding TDs associated with this request */
 } urb_priv_t;
 #define URB_DEL 1
@@ -357,6 +381,7 @@ typedef struct ohci {
 
 	struct ohci_regs *regs; /* OHCI controller's memory */
 
+	int ohci_int_load[32];	 /* load of the 32 Interrupt Chains (for load balancing)*/
 	ed_t *ed_rm_list[2];	 /* lists of all endpoints to be removed */
 	ed_t *ed_bulktail;	 /* last endpoint of bulk list */
 	ed_t *ed_controltail;	 /* last endpoint of control list */
@@ -379,7 +404,8 @@ struct ohci_device {
 /* endpoint */
 static int ep_link(ohci_t * ohci, ed_t * ed);
 static int ep_unlink(ohci_t * ohci, ed_t * ed);
-static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe);
+static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe,
+		int interval, int load);
 
 /*-------------------------------------------------------------------------*/
 
diff --git a/drivers/usbdcore_ep0.c b/drivers/usbdcore_ep0.c
index 260befe9786d6cb80a8fe290b931514344745c5c..1e44f322a7977513630df0011ec852e6f0351750 100644
--- a/drivers/usbdcore_ep0.c
+++ b/drivers/usbdcore_ep0.c
@@ -2,6 +2,9 @@
  * (C) Copyright 2003
  * Gerry Hamel, geh@ti.com, Texas Instruments
  *
+ * (C) Copyright 2006
+ * Bryan O'Donoghue, deckard@CodeHermit.ie
+ *
  * Based on
  * linux/drivers/usbd/ep0.c
  *
@@ -39,11 +42,17 @@
  * function driver. This may need to change.
  *
  * XXX
+ *
+ * As alluded to above, a simple callback cdc_recv_setup has been implemented
+ * in the usb_device data structure to facilicate passing
+ * Common Device Class packets to a function driver.
+ *
+ * XXX
  */
 
 #include <common.h>
 
-#if defined(CONFIG_OMAP1510) && defined(CONFIG_USB_DEVICE)
+#if defined(CONFIG_USB_DEVICE)
 #include "usbdcore.h"
 
 #if 0
@@ -69,7 +78,7 @@ static int ep0_get_status (struct usb_device_instance *device,
 	char *cp;
 
 	urb->actual_length = 2;
-	cp = urb->buffer;
+	cp = (char*)urb->buffer;
 	cp[0] = cp[1] = 0;
 
 	switch (requesttype) {
@@ -115,7 +124,7 @@ static int ep0_get_one (struct usb_device_instance *device, struct urb *urb,
  *
  * Copy configuration data to urb transfer buffer if there is room for it.
  */
-static void copy_config (struct urb *urb, void *data, int max_length,
+void copy_config (struct urb *urb, void *data, int max_length,
 			 int max_buf)
 {
 	int available;
@@ -128,10 +137,7 @@ static void copy_config (struct urb *urb, void *data, int max_length,
 		dbg_ep0 (1, "data is NULL");
 		return;
 	}
-	if (!(length = *(unsigned char *) data)) {
-		dbg_ep0 (1, "length is zero");
-		return;
-	}
+	length = max_length;
 
 	if (length > max_length) {
 		dbg_ep0 (1, "length: %d >= max_length: %d", length,
@@ -192,7 +198,7 @@ static int ep0_get_descriptor (struct usb_device_instance *device,
 
 	/* setup tx urb */
 	urb->actual_length = 0;
-	cp = urb->buffer;
+	cp = (char*)urb->buffer;
 
 	dbg_ep0 (2, "%s", USBD_DEVICE_DESCRIPTORS (descriptor_type));
 
@@ -200,7 +206,6 @@ static int ep0_get_descriptor (struct usb_device_instance *device,
 	case USB_DESCRIPTOR_TYPE_DEVICE:
 		{
 			struct usb_device_descriptor *device_descriptor;
-
 			if (!
 			    (device_descriptor =
 			     usbd_device_device_descriptor (device, port))) {
@@ -214,20 +219,16 @@ static int ep0_get_descriptor (struct usb_device_instance *device,
 			/* correct the correct control endpoint 0 max packet size into the descriptor */
 			device_descriptor =
 				(struct usb_device_descriptor *) urb->buffer;
-			device_descriptor->bMaxPacketSize0 =
-				urb->device->bus->maxpacketsize;
 
 		}
-		/*dbg_ep0(3, "copied device configuration, actual_length: %x", urb->actual_length); */
+		dbg_ep0(3, "copied device configuration, actual_length: 0x%x", urb->actual_length);
 		break;
 
 	case USB_DESCRIPTOR_TYPE_CONFIGURATION:
 		{
-			int bNumInterface;
 			struct usb_configuration_descriptor
 				*configuration_descriptor;
 			struct usb_device_descriptor *device_descriptor;
-
 			if (!
 			    (device_descriptor =
 			     usbd_device_device_descriptor (device, port))) {
@@ -251,130 +252,35 @@ static int ep0_get_descriptor (struct usb_device_instance *device,
 					 index);
 				return -1;
 			}
+			dbg_ep0(0, "attempt to copy %d bytes to urb\n",cpu_to_le16(configuration_descriptor->wTotalLength));
 			copy_config (urb, configuration_descriptor,
-				     sizeof (struct
-					     usb_configuration_descriptor),
-				     max);
-
-
-			/* iterate across interfaces for specified configuration */
-			dbg_ep0 (0, "bNumInterfaces: %d",
-				 configuration_descriptor->bNumInterfaces);
-			for (bNumInterface = 0;
-			     bNumInterface <
-			     configuration_descriptor->bNumInterfaces;
-			     bNumInterface++) {
 
-				int bAlternateSetting;
-				struct usb_interface_instance
-					*interface_instance;
-
-				dbg_ep0 (3, "[%d] bNumInterfaces: %d",
-					 bNumInterface,
-					 configuration_descriptor->bNumInterfaces);
-
-				if (! (interface_instance = usbd_device_interface_instance (device,
-								     port, index, bNumInterface)))
-				{
-					dbg_ep0 (3, "[%d] interface_instance NULL",
-						 bNumInterface);
-					return -1;
-				}
-				/* iterate across interface alternates */
-				for (bAlternateSetting = 0;
-				     bAlternateSetting < interface_instance->alternates;
-				     bAlternateSetting++) {
-					/*int class; */
-					int bNumEndpoint;
-					struct usb_interface_descriptor *interface_descriptor;
-
-					struct usb_alternate_instance *alternate_instance;
-
-					dbg_ep0 (3, "[%d:%d] alternates: %d",
-						 bNumInterface,
-						 bAlternateSetting,
-						 interface_instance->alternates);
-
-					if (! (alternate_instance = usbd_device_alternate_instance (device, port, index, bNumInterface, bAlternateSetting))) {
-						dbg_ep0 (3, "[%d] alternate_instance NULL",
-							 bNumInterface);
-						return -1;
-					}
-					/* copy descriptor for this interface */
-					copy_config (urb, alternate_instance->interface_descriptor,
-						     sizeof (struct usb_interface_descriptor),
-						     max);
-
-					/*dbg_ep0(3, "[%d:%d] classes: %d endpoints: %d", bNumInterface, bAlternateSetting, */
-					/*        alternate_instance->classes, alternate_instance->endpoints); */
-
-					/* iterate across classes for this alternate interface */
-#if 0
-					for (class = 0;
-					     class < alternate_instance->classes;
-					     class++) {
-						struct usb_class_descriptor *class_descriptor;
-						/*dbg_ep0(3, "[%d:%d:%d] classes: %d", bNumInterface, bAlternateSetting, */
-						/*        class, alternate_instance->classes); */
-						if (!(class_descriptor = usbd_device_class_descriptor_index (device, port, index, bNumInterface, bAlternateSetting, class))) {
-							dbg_ep0 (3, "[%d] class NULL",
-								 class);
-							return -1;
-						}
-						/* copy descriptor for this class */
-						copy_config (urb, class_descriptor,
-							sizeof (struct usb_class_descriptor),
-							max);
-					}
-#endif
-
-					/* iterate across endpoints for this alternate interface */
-					interface_descriptor = alternate_instance->interface_descriptor;
-					for (bNumEndpoint = 0;
-					     bNumEndpoint < alternate_instance->endpoints;
-					     bNumEndpoint++) {
-						struct usb_endpoint_descriptor *endpoint_descriptor;
-						dbg_ep0 (3, "[%d:%d:%d] endpoint: %d",
-							 bNumInterface,
-							 bAlternateSetting,
-							 bNumEndpoint,
-							 interface_descriptor->
-							 bNumEndpoints);
-						if (!(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, port, index, bNumInterface, bAlternateSetting, bNumEndpoint))) {
-							dbg_ep0 (3, "[%d] endpoint NULL",
-								 bNumEndpoint);
-							return -1;
-						}
-						/* copy descriptor for this endpoint */
-						copy_config (urb, endpoint_descriptor,
-							     sizeof (struct usb_endpoint_descriptor),
-							     max);
-					}
-				}
-			}
-			dbg_ep0 (3, "lengths: %d %d",
-				 le16_to_cpu (configuration_descriptor->wTotalLength),
-				 urb->actual_length);
+					cpu_to_le16(configuration_descriptor->wTotalLength),
+				     max);
 		}
+
 		break;
 
 	case USB_DESCRIPTOR_TYPE_STRING:
 		{
 			struct usb_string_descriptor *string_descriptor;
-
 			if (!(string_descriptor = usbd_get_string (index))) {
+				serial_printf("Invalid string index %d\n", index);
 				return -1;
 			}
-			/*dbg_ep0(3, "string_descriptor: %p", string_descriptor); */
+			dbg_ep0(3, "string_descriptor: %p length %d", string_descriptor, string_descriptor->bLength);
 			copy_config (urb, string_descriptor, string_descriptor->bLength, max);
 		}
 		break;
 	case USB_DESCRIPTOR_TYPE_INTERFACE:
+	serial_printf("USB_DESCRIPTOR_TYPE_INTERFACE - error not implemented\n");
 		return -1;
 	case USB_DESCRIPTOR_TYPE_ENDPOINT:
+		serial_printf("USB_DESCRIPTOR_TYPE_ENDPOINT - error not implemented\n");
 		return -1;
 	case USB_DESCRIPTOR_TYPE_HID:
 		{
+			serial_printf("USB_DESCRIPTOR_TYPE_HID - error not implemented\n");
 			return -1;	/* unsupported at this time */
 #if 0
 			int bNumInterface =
@@ -403,6 +309,7 @@ static int ep0_get_descriptor (struct usb_device_instance *device,
 		break;
 	case USB_DESCRIPTOR_TYPE_REPORT:
 		{
+			serial_printf("USB_DESCRIPTOR_TYPE_REPORT - error not implemented\n");
 			return -1;	/* unsupported at this time */
 #if 0
 			int bNumInterface =
@@ -434,12 +341,19 @@ static int ep0_get_descriptor (struct usb_device_instance *device,
 #endif
 		}
 		break;
+	case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
+		{
+			/* If a USB device supports both a full speed and low speed operation
+			 * we must send a Device_Qualifier descriptor here
+			 */
+			return -1;
+		}
 	default:
 		return -1;
 	}
 
 
-	dbg_ep0 (1, "urb: buffer: %p buffer_length: %2d actual_length: %2d packet size: %2d",
+	dbg_ep0 (1, "urb: buffer: %p buffer_length: %2d actual_length: %2d tx_packetSize: %2d",
 		 urb->buffer, urb->buffer_length, urb->actual_length,
 		 device->bus->endpoint_array[0].tx_packetSize);
 /*
@@ -495,6 +409,12 @@ int ep0_recv_setup (struct urb *urb)
 
 	/* handle USB Standard Request (c.f. USB Spec table 9-2) */
 	if ((request->bmRequestType & USB_REQ_TYPE_MASK) != 0) {
+		if(device->device_state <= STATE_CONFIGURED){
+			/*	Attempt to handle a CDC specific request if we are
+			 *	in the configured state.
+			 */
+			return device->cdc_recv_setup(request,urb);
+		}
 		dbg_ep0 (1, "non standard request: %x",
 			 request->bmRequestType & USB_REQ_TYPE_MASK);
 		return -1;	/* Stall here */
@@ -567,6 +487,7 @@ int ep0_recv_setup (struct urb *urb)
 						   le16_to_cpu (request->wValue) & 0xff);
 
 		case USB_REQ_GET_CONFIGURATION:
+			serial_printf("get config %d\n", device->configuration);
 			return ep0_get_one (device, urb,
 					    device->configuration);
 
@@ -642,7 +563,6 @@ int ep0_recv_setup (struct urb *urb)
 			/*dbg_ep0(2, "address: %d %d %d", */
 			/*        request->wValue, le16_to_cpu(request->wValue), device->address); */
 
-			serial_printf ("DEVICE_ADDRESS_ASSIGNED.. event?\n");
 			return 0;
 
 		case USB_REQ_SET_DESCRIPTOR:	/* XXX should we support this? */
@@ -653,9 +573,10 @@ int ep0_recv_setup (struct urb *urb)
 			/* c.f. 9.4.7 - the top half of wValue is reserved */
 			/* */
 			if ((device->configuration =
-			     le16_to_cpu (request->wValue) & 0x7f) != 0) {
+				le16_to_cpu (request->wValue) & 0xFF80) != 0) {
 				/* c.f. 9.4.7 - zero is the default or addressed state, in our case this */
 				/* is the same is configuration zero */
+				serial_printf("error setting dev->config to zero!\n");
 				device->configuration = 0;	/* TBR - ?????? */
 			}
 			/* reset interface and alternate settings */
diff --git a/drivers/usbdcore_mpc8xx.c b/drivers/usbdcore_mpc8xx.c
new file mode 100644
index 0000000000000000000000000000000000000000..e87284b1787dbd4d19dc5e387329fe0072725018
--- /dev/null
+++ b/drivers/usbdcore_mpc8xx.c
@@ -0,0 +1,1400 @@
+/*
+ * Copyright (C) 2006 by Bryan O'Donoghue, CodeHermit
+ * bodonoghue@CodeHermit.ie
+ *
+ * References
+ * DasUBoot/drivers/usbdcore_omap1510.c, for design and implementation ideas.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * Notes :
+ * 1.	#define __SIMULATE_ERROR__ to inject a CRC error into every 2nd TX
+ *		packet to force the USB re-transmit protocol.
+ *
+ * 2.	#define __DEBUG_UDC__ to switch on debug tracing to serial console
+ *	be careful that tracing doesn't create Hiesen-bugs with respect to
+ *	response timeouts to control requests.
+ *
+ * 3.	This driver should be able to support any higher level driver that
+ *	that wants to do either of the two standard UDC implementations
+ *	Control-Bulk-Interrupt or  Bulk-IN/Bulk-Out standards. Hence
+ *	gserial and cdc_acm should work with this code.
+ *
+ * 4.	NAK events never actually get raised at all, the documentation
+ *	is just wrong !
+ *
+ * 5.	For some reason, cbd_datlen is *always* +2 the value it should be.
+ *	this means that having an RX cbd of 16 bytes is not possible, since
+ *	the same size is reported for 14 bytes received as 16 bytes received
+ *	until we can find out why this happens, RX cbds must be limited to 8
+ *	bytes. TODO: check errata for this behaviour.
+ *
+ * 6.	Right now this code doesn't support properly powering up with the USB
+ *	cable attached to the USB host my development board the Adder87x doesn't
+ *	have a pull-up fitted to allow this, so it is necessary to power the
+ *	board and *then* attached the USB cable to the host. However somebody
+ *	with a different design in their board may be able to keep the cable
+ *	constantly connected and simply enable/disable a pull-up  re
+ *	figure 31.1 in MPC885RM.pdf instead of having to power up the board and
+ *	then attach the cable !
+ *
+ */
+#include <common.h>
+#include <config.h>
+
+#if defined(CONFIG_MPC885_FAMILY) && defined(CONFIG_USB_DEVICE)
+#include <commproc.h>
+#include "usbdcore.h"
+#include "usbdcore_mpc8xx.h"
+#include "usbdcore_ep0.h"
+
+#define ERR(fmt, args...)\
+	serial_printf("ERROR : [%s] %s:%d: "fmt,\
+				__FILE__,__FUNCTION__,__LINE__, ##args)
+#ifdef __DEBUG_UDC__
+#define DBG(fmt,args...)\
+		serial_printf("[%s] %s:%d: "fmt,\
+				__FILE__,__FUNCTION__,__LINE__, ##args)
+#else
+#define DBG(fmt,args...)
+#endif
+
+/* Static Data */
+#ifdef __SIMULATE_ERROR__
+static char err_poison_test = 0;
+#endif
+static struct mpc8xx_ep ep_ref[MAX_ENDPOINTS];
+static u32 address_base = STATE_NOT_READY;
+static mpc8xx_udc_state_t udc_state = 0;
+static struct usb_device_instance *udc_device = 0;
+static volatile usb_epb_t *endpoints[MAX_ENDPOINTS];
+static volatile cbd_t *tx_cbd[TX_RING_SIZE];
+static volatile cbd_t *rx_cbd[RX_RING_SIZE];
+static volatile immap_t *immr = 0;
+static volatile cpm8xx_t *cp = 0;
+static volatile usb_pram_t *usb_paramp = 0;
+static volatile usb_t *usbp = 0;
+static int rx_ct = 0;
+static int tx_ct = 0;
+
+/* Static Function Declarations */
+static void mpc8xx_udc_state_transition_up (usb_device_state_t initial,
+					    usb_device_state_t final);
+static void mpc8xx_udc_state_transition_down (usb_device_state_t initial,
+					      usb_device_state_t final);
+static void mpc8xx_udc_stall (unsigned int ep);
+static void mpc8xx_udc_flush_tx_fifo (int epid);
+static void mpc8xx_udc_flush_rx_fifo (void);
+static void mpc8xx_udc_clear_rxbd (volatile cbd_t * rx_cbdp);
+static void mpc8xx_udc_init_tx (struct usb_endpoint_instance *epi,
+				struct urb *tx_urb);
+static void mpc8xx_udc_dump_request (struct usb_device_request *request);
+static void mpc8xx_udc_clock_init (volatile immap_t * immr,
+				   volatile cpm8xx_t * cp);
+static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi);
+static int mpc8xx_udc_epn_rx (unsigned int epid, volatile cbd_t * rx_cbdp);
+static void mpc8xx_udc_ep0_rx (volatile cbd_t * rx_cbdp);
+static void mpc8xx_udc_cbd_init (void);
+static void mpc8xx_udc_endpoint_init (void);
+static void mpc8xx_udc_cbd_attach (int ep, uchar tx_size, uchar rx_size);
+static u32 mpc8xx_udc_alloc (u32 data_size, u32 alignment);
+static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp);
+static void mpc8xx_udc_set_nak (unsigned int ep);
+static short mpc8xx_udc_handle_txerr (void);
+static void mpc8xx_udc_advance_rx (volatile cbd_t ** rx_cbdp, int epid);
+
+/******************************************************************************
+			       Global Linkage
+ *****************************************************************************/
+
+/* udc_init
+ *
+ * Do initial bus gluing
+ */
+int udc_init (void)
+{
+	/* Init various pointers */
+	immr = (immap_t *) CFG_IMMR;
+	cp = (cpm8xx_t *) & (immr->im_cpm);
+	usb_paramp = (usb_pram_t *) & (cp->cp_dparam[PROFF_USB]);
+	usbp = (usb_t *) & (cp->cp_scc[0]);
+
+	memset (ep_ref, 0x00, (sizeof (struct mpc8xx_ep) * MAX_ENDPOINTS));
+
+	udc_device = 0;
+	udc_state = STATE_NOT_READY;
+
+	usbp->usmod = 0x00;
+	usbp->uscom = 0;
+
+	/* Set USB Frame #0, Respond at Address & Get a clock source  */
+	usbp->usaddr = 0x00;
+	mpc8xx_udc_clock_init (immr, cp);
+
+	/* PA15, PA14 as perhiperal USBRXD and USBOE */
+	immr->im_ioport.iop_padir &= ~0x0003;
+	immr->im_ioport.iop_papar |= 0x0003;
+
+	/* PC11/PC10 as peripheral USBRXP USBRXN */
+	immr->im_ioport.iop_pcso |= 0x0030;
+
+	/* PC7/PC6 as perhiperal USBTXP and USBTXN */
+	immr->im_ioport.iop_pcdir |= 0x0300;
+	immr->im_ioport.iop_pcpar |= 0x0300;
+
+	/* Set the base address */
+	address_base = (u32) (cp->cp_dpmem + CPM_USB_BASE);
+
+	/* Initialise endpoints and circular buffers */
+	mpc8xx_udc_endpoint_init ();
+	mpc8xx_udc_cbd_init ();
+
+	/* Assign allocated Dual Port Endpoint descriptors */
+	usb_paramp->ep0ptr = (u32) endpoints[0];
+	usb_paramp->ep1ptr = (u32) endpoints[1];
+	usb_paramp->ep2ptr = (u32) endpoints[2];
+	usb_paramp->ep3ptr = (u32) endpoints[3];
+	usb_paramp->frame_n = 0;
+
+	DBG ("ep0ptr=0x%08x ep1ptr=0x%08x ep2ptr=0x%08x ep3ptr=0x%08x\n",
+	     usb_paramp->ep0ptr, usb_paramp->ep1ptr, usb_paramp->ep2ptr,
+	     usb_paramp->ep3ptr);
+
+	return 0;
+}
+
+/* udc_irq
+ *
+ * Poll for whatever events may have occured
+ */
+void udc_irq (void)
+{
+	int epid = 0;
+	volatile cbd_t *rx_cbdp = 0;
+	volatile cbd_t *rx_cbdp_base = 0;
+
+	if (udc_state != STATE_READY) {
+		return;
+	}
+
+	if (usbp->usber & USB_E_BSY) {
+		/* This shouldn't happen. If it does then it's a bug ! */
+		usbp->usber |= USB_E_BSY;
+		mpc8xx_udc_flush_rx_fifo ();
+	}
+
+	/* Scan all RX/Bidirectional Endpoints for RX data. */
+	for (epid = 0; epid < MAX_ENDPOINTS; epid++) {
+		if (!ep_ref[epid].prx) {
+			continue;
+		}
+		rx_cbdp = rx_cbdp_base = ep_ref[epid].prx;
+
+		do {
+			if (!(rx_cbdp->cbd_sc & RX_BD_E)) {
+
+				if (rx_cbdp->cbd_sc & 0x1F) {
+					/* Corrupt data discard it.
+					 * Controller has NAK'd this packet.
+					 */
+					mpc8xx_udc_clear_rxbd (rx_cbdp);
+
+				} else {
+					if (!epid) {
+						mpc8xx_udc_ep0_rx (rx_cbdp);
+
+					} else {
+						/* Process data */
+						mpc8xx_udc_set_nak (epid);
+						mpc8xx_udc_epn_rx (epid, rx_cbdp);
+						mpc8xx_udc_clear_rxbd (rx_cbdp);
+					}
+				}
+
+				/* Advance RX CBD pointer */
+				mpc8xx_udc_advance_rx (&rx_cbdp, epid);
+				ep_ref[epid].prx = rx_cbdp;
+			} else {
+				/* Advance RX CBD pointer */
+				mpc8xx_udc_advance_rx (&rx_cbdp, epid);
+			}
+
+		} while (rx_cbdp != rx_cbdp_base);
+	}
+
+	/* Handle TX events as appropiate, the correct place to do this is
+	 * in a tx routine. Perhaps TX on epn was pre-empted by ep0
+	 */
+
+	if (usbp->usber & USB_E_TXB) {
+		usbp->usber |= USB_E_TXB;
+	}
+
+	if (usbp->usber & (USB_TX_ERRMASK)) {
+		mpc8xx_udc_handle_txerr ();
+	}
+
+	/* Switch to the default state, respond at the default address */
+	if (usbp->usber & USB_E_RESET) {
+		usbp->usber |= USB_E_RESET;
+		usbp->usaddr = 0x00;
+		udc_device->device_state = STATE_DEFAULT;
+	}
+
+	/* if(usbp->usber&USB_E_IDLE){
+	   We could suspend here !
+	   usbp->usber|=USB_E_IDLE;
+	   DBG("idle state change\n");
+	   }
+	   if(usbp->usbs){
+	   We could resume here when IDLE is deasserted !
+	   Not worth doing, so long as we are self powered though.
+	   }
+	*/
+
+	return;
+}
+
+/* udc_endpoint_write
+ *
+ * Write some data to an endpoint
+ */
+int udc_endpoint_write (struct usb_endpoint_instance *epi)
+{
+	int ep = 0;
+	short epid = 1, unnak = 0, ret = 0;
+
+	if (udc_state != STATE_READY) {
+		ERR ("invalid udc_state != STATE_READY!\n");
+		return -1;
+	}
+
+	if (!udc_device || !epi) {
+		return -1;
+	}
+
+	if (udc_device->device_state != STATE_CONFIGURED) {
+		return -1;
+	}
+
+	ep = epi->endpoint_address & 0x03;
+	if (ep >= MAX_ENDPOINTS) {
+		return -1;
+	}
+
+	/* Set NAK for all RX endpoints during TX */
+	for (epid = 1; epid < MAX_ENDPOINTS; epid++) {
+
+		/* Don't set NAK on DATA IN/CONTROL endpoints */
+		if (ep_ref[epid].sc & USB_DIR_IN) {
+			continue;
+		}
+
+		if (!(usbp->usep[epid] & (USEP_THS_NAK | USEP_RHS_NAK))) {
+			unnak |= 1 << epid;
+		}
+
+		mpc8xx_udc_set_nak (epid);
+	}
+
+	mpc8xx_udc_init_tx (&udc_device->bus->endpoint_array[ep],
+			    epi->tx_urb);
+	ret = mpc8xx_udc_ep_tx (&udc_device->bus->endpoint_array[ep]);
+
+	/* Remove temporary NAK */
+	for (epid = 1; epid < MAX_ENDPOINTS; epid++) {
+		if (unnak & (1 << epid)) {
+			udc_unset_nak (epid);
+		}
+	}
+
+	return ret;
+}
+
+/* mpc8xx_udc_assign_urb
+ *
+ * Associate a given urb to an endpoint TX or RX transmit/receive buffers
+ */
+static int mpc8xx_udc_assign_urb (int ep, char direction)
+{
+	struct usb_endpoint_instance *epi = 0;
+
+	if (ep >= MAX_ENDPOINTS) {
+		goto err;
+	}
+	epi = &udc_device->bus->endpoint_array[ep];
+	if (!epi) {
+		goto err;
+	}
+
+	if (!ep_ref[ep].urb) {
+		ep_ref[ep].urb = usbd_alloc_urb (udc_device, udc_device->bus->endpoint_array);
+		if (!ep_ref[ep].urb) {
+			goto err;
+		}
+	} else {
+		ep_ref[ep].urb->actual_length = 0;
+	}
+
+	switch (direction) {
+	case USB_DIR_IN:
+		epi->tx_urb = ep_ref[ep].urb;
+		break;
+	case USB_DIR_OUT:
+		epi->rcv_urb = ep_ref[ep].urb;
+		break;
+	default:
+		goto err;
+	}
+	return 0;
+
+      err:
+	udc_state = STATE_ERROR;
+	return -1;
+}
+
+/* udc_setup_ep
+ *
+ * Associate U-Boot software endpoints to mpc8xx endpoint parameter ram
+ * Isochronous endpoints aren't yet supported!
+ */
+void udc_setup_ep (struct usb_device_instance *device, unsigned int ep,
+		   struct usb_endpoint_instance *epi)
+{
+	uchar direction = 0;
+	int ep_attrib = 0;
+
+	if (epi && (ep < MAX_ENDPOINTS)) {
+
+		if (ep == 0) {
+			if (epi->rcv_attributes != USB_ENDPOINT_XFER_CONTROL
+			    || epi->tx_attributes !=
+			    USB_ENDPOINT_XFER_CONTROL) {
+
+				/* ep0 must be a control endpoint */
+				udc_state = STATE_ERROR;
+				return;
+
+			}
+			if (!(ep_ref[ep].sc & EP_ATTACHED)) {
+				mpc8xx_udc_cbd_attach (ep, epi->tx_packetSize,
+						       epi->rcv_packetSize);
+			}
+			usbp->usep[ep] = 0x0000;
+			return;
+		}
+
+		if ((epi->endpoint_address & USB_ENDPOINT_DIR_MASK)
+		    == USB_DIR_IN) {
+
+			direction = 1;
+			ep_attrib = epi->tx_attributes;
+			epi->rcv_packetSize = 0;
+			ep_ref[ep].sc |= USB_DIR_IN;
+		} else {
+
+			direction = 0;
+			ep_attrib = epi->rcv_attributes;
+			epi->tx_packetSize = 0;
+			ep_ref[ep].sc &= ~USB_DIR_IN;
+		}
+
+		if (mpc8xx_udc_assign_urb (ep, epi->endpoint_address
+					   & USB_ENDPOINT_DIR_MASK)) {
+			return;
+		}
+
+		switch (ep_attrib) {
+		case USB_ENDPOINT_XFER_CONTROL:
+			if (!(ep_ref[ep].sc & EP_ATTACHED)) {
+				mpc8xx_udc_cbd_attach (ep,
+						       epi->tx_packetSize,
+						       epi->rcv_packetSize);
+			}
+			usbp->usep[ep] = ep << 12;
+			epi->rcv_urb = epi->tx_urb = ep_ref[ep].urb;
+
+			break;
+		case USB_ENDPOINT_XFER_BULK:
+		case USB_ENDPOINT_XFER_INT:
+			if (!(ep_ref[ep].sc & EP_ATTACHED)) {
+				if (direction) {
+					mpc8xx_udc_cbd_attach (ep,
+							       epi->tx_packetSize,
+							       0);
+				} else {
+					mpc8xx_udc_cbd_attach (ep,
+							       0,
+							       epi->rcv_packetSize);
+				}
+			}
+			usbp->usep[ep] = (ep << 12) | ((ep_attrib) << 8);
+
+			break;
+		case USB_ENDPOINT_XFER_ISOC:
+		default:
+			serial_printf ("Error endpoint attrib %d>3\n", ep_attrib);
+			udc_state = STATE_ERROR;
+			break;
+		}
+	}
+
+}
+
+/* udc_connect
+ *
+ * Move state, switch on the USB
+ */
+void udc_connect (void)
+{
+	/* Enable pull-up resistor on D+
+	 * TODO: fit a pull-up resistor to drive SE0 for > 2.5us
+	 */
+
+	if (udc_state != STATE_ERROR) {
+		udc_state = STATE_READY;
+		usbp->usmod |= USMOD_EN;
+	}
+}
+
+/* udc_disconnect
+ *
+ * Disconnect is not used but, is included for completeness
+ */
+void udc_disconnect (void)
+{
+	/* Disable pull-up resistor on D-
+	 * TODO: fix a pullup resistor to control this
+	 */
+
+	if (udc_state != STATE_ERROR) {
+		udc_state = STATE_NOT_READY;
+	}
+	usbp->usmod &= ~USMOD_EN;
+}
+
+/* udc_enable
+ *
+ * Grab an EP0 URB, register interest in a subset of USB events
+ */
+void udc_enable (struct usb_device_instance *device)
+{
+	if (udc_state == STATE_ERROR) {
+		return;
+	}
+
+	udc_device = device;
+
+	if (!ep_ref[0].urb) {
+		ep_ref[0].urb = usbd_alloc_urb (device, device->bus->endpoint_array);
+	}
+
+	/* Register interest in all events except SOF, enable transceiver */
+	usbp->usber = 0x03FF;
+	usbp->usbmr = 0x02F7;
+
+	return;
+}
+
+/* udc_disable
+ *
+ * disable the currently hooked device
+ */
+void udc_disable (void)
+{
+	int i = 0;
+
+	if (udc_state == STATE_ERROR) {
+		DBG ("Won't disable UDC. udc_state==STATE_ERROR !\n");
+		return;
+	}
+
+	udc_device = 0;
+
+	for (; i < MAX_ENDPOINTS; i++) {
+		if (ep_ref[i].urb) {
+			usbd_dealloc_urb (ep_ref[i].urb);
+			ep_ref[i].urb = 0;
+		}
+	}
+
+	usbp->usbmr = 0x00;
+	usbp->usmod = ~USMOD_EN;
+	udc_state = STATE_NOT_READY;
+}
+
+/* udc_startup_events
+ *
+ * Enable the specified device
+ */
+void udc_startup_events (struct usb_device_instance *device)
+{
+	udc_enable (device);
+	if (udc_state == STATE_READY) {
+		usbd_device_event_irq (device, DEVICE_CREATE, 0);
+	}
+}
+
+/* udc_set_nak
+ *
+ * Allow upper layers to signal lower layers should not accept more RX data
+ *
+ */
+void udc_set_nak (int epid)
+{
+	if (epid) {
+		mpc8xx_udc_set_nak (epid);
+	}
+}
+
+/* udc_unset_nak
+ *
+ * Suspend sending of NAK tokens for DATA OUT tokens on a given endpoint.
+ * Switch off NAKing on this endpoint to accept more data output from host.
+ *
+ */
+void udc_unset_nak (int epid)
+{
+	if (epid > MAX_ENDPOINTS) {
+		return;
+	}
+
+	if (usbp->usep[epid] & (USEP_THS_NAK | USEP_RHS_NAK)) {
+		usbp->usep[epid] &= ~(USEP_THS_NAK | USEP_RHS_NAK);
+		__asm__ ("eieio");
+	}
+}
+
+/******************************************************************************
+			      Static Linkage
+******************************************************************************/
+
+/* udc_state_transition_up
+ * udc_state_transition_down
+ *
+ * Helper functions to implement device state changes.	The device states and
+ * the events that transition between them are:
+ *
+ *				STATE_ATTACHED
+ *				||	/\
+ *				\/	||
+ *	DEVICE_HUB_CONFIGURED			DEVICE_HUB_RESET
+ *				||	/\
+ *				\/	||
+ *				STATE_POWERED
+ *				||	/\
+ *				\/	||
+ *	DEVICE_RESET				DEVICE_POWER_INTERRUPTION
+ *				||	/\
+ *				\/	||
+ *				STATE_DEFAULT
+ *				||	/\
+ *				\/	||
+ *	DEVICE_ADDRESS_ASSIGNED			DEVICE_RESET
+ *				||	/\
+ *				\/	||
+ *				STATE_ADDRESSED
+ *				||	/\
+ *				\/	||
+ *	DEVICE_CONFIGURED			DEVICE_DE_CONFIGURED
+ *				||	/\
+ *				\/	||
+ *				STATE_CONFIGURED
+ *
+ * udc_state_transition_up transitions up (in the direction from STATE_ATTACHED
+ * to STATE_CONFIGURED) from the specified initial state to the specified final
+ * state, passing through each intermediate state on the way.  If the initial
+ * state is at or above (i.e. nearer to STATE_CONFIGURED) the final state, then
+ * no state transitions will take place.
+ *
+ * udc_state_transition_down transitions down (in the direction from
+ * STATE_CONFIGURED to STATE_ATTACHED) from the specified initial state to the
+ * specified final state, passing through each intermediate state on the way.
+ * If the initial state is at or below (i.e. nearer to STATE_ATTACHED) the final
+ * state, then no state transitions will take place.
+ *
+ */
+
+static void mpc8xx_udc_state_transition_up (usb_device_state_t initial,
+					    usb_device_state_t final)
+{
+	if (initial < final) {
+		switch (initial) {
+		case STATE_ATTACHED:
+			usbd_device_event_irq (udc_device,
+					       DEVICE_HUB_CONFIGURED, 0);
+			if (final == STATE_POWERED)
+				break;
+		case STATE_POWERED:
+			usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
+			if (final == STATE_DEFAULT)
+				break;
+		case STATE_DEFAULT:
+			usbd_device_event_irq (udc_device,
+					       DEVICE_ADDRESS_ASSIGNED, 0);
+			if (final == STATE_ADDRESSED)
+				break;
+		case STATE_ADDRESSED:
+			usbd_device_event_irq (udc_device, DEVICE_CONFIGURED,
+					       0);
+		case STATE_CONFIGURED:
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+static void mpc8xx_udc_state_transition_down (usb_device_state_t initial,
+					      usb_device_state_t final)
+{
+	if (initial > final) {
+		switch (initial) {
+		case STATE_CONFIGURED:
+			usbd_device_event_irq (udc_device,
+					       DEVICE_DE_CONFIGURED, 0);
+			if (final == STATE_ADDRESSED)
+				break;
+		case STATE_ADDRESSED:
+			usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
+			if (final == STATE_DEFAULT)
+				break;
+		case STATE_DEFAULT:
+			usbd_device_event_irq (udc_device,
+					       DEVICE_POWER_INTERRUPTION, 0);
+			if (final == STATE_POWERED)
+				break;
+		case STATE_POWERED:
+			usbd_device_event_irq (udc_device, DEVICE_HUB_RESET,
+					       0);
+		case STATE_ATTACHED:
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+/* mpc8xx_udc_stall
+ *
+ * Force returning of STALL tokens on the given endpoint. Protocol or function
+ * STALL conditions are permissable here
+ */
+static void mpc8xx_udc_stall (unsigned int ep)
+{
+	usbp->usep[ep] |= STALL_BITMASK;
+}
+
+/* mpc8xx_udc_set_nak
+ *
+ * Force returning of NAK responses for the given endpoint as a kind of very
+ * simple flow control
+ */
+static void mpc8xx_udc_set_nak (unsigned int ep)
+{
+	usbp->usep[ep] |= NAK_BITMASK;
+	__asm__ ("eieio");
+}
+
+/* mpc8xx_udc_handle_txerr
+ *
+ * Handle errors relevant to TX. Return a status code to allow calling
+ * indicative of what if anything happened
+ */
+static short mpc8xx_udc_handle_txerr ()
+{
+	short ep = 0, ret = 0;
+
+	for (; ep < TX_RING_SIZE; ep++) {
+		if (usbp->usber & (0x10 << ep)) {
+
+			/* Timeout or underrun */
+			if (tx_cbd[ep]->cbd_sc & 0x06) {
+				ret = 1;
+				mpc8xx_udc_flush_tx_fifo (ep);
+
+			} else {
+				if (usbp->usep[ep] & STALL_BITMASK) {
+					if (!ep) {
+						usbp->usep[ep] &= ~STALL_BITMASK;
+					}
+				}	/* else NAK */
+			}
+			usbp->usber |= (0x10 << ep);
+		}
+	}
+	return ret;
+}
+
+/* mpc8xx_udc_advance_rx
+ *
+ * Advance cbd rx
+ */
+static void mpc8xx_udc_advance_rx (volatile cbd_t ** rx_cbdp, int epid)
+{
+	if ((*rx_cbdp)->cbd_sc & RX_BD_W) {
+		*rx_cbdp = (volatile cbd_t *) (endpoints[epid]->rbase + CFG_IMMR);
+
+	} else {
+		(*rx_cbdp)++;
+	}
+}
+
+
+/* mpc8xx_udc_flush_tx_fifo
+ *
+ * Flush a given TX fifo. Assumes one tx cbd per endpoint
+ */
+static void mpc8xx_udc_flush_tx_fifo (int epid)
+{
+	volatile cbd_t *tx_cbdp = 0;
+
+	if (epid > MAX_ENDPOINTS) {
+		return;
+	}
+
+	/* TX stop */
+	immr->im_cpm.cp_cpcr = ((epid << 2) | 0x1D01);
+	__asm__ ("eieio");
+	while (immr->im_cpm.cp_cpcr & 0x01);
+
+	usbp->uscom = 0x40 | 0;
+
+	/* reset ring */
+	tx_cbdp = (cbd_t *) (endpoints[epid]->tbptr + CFG_IMMR);
+	tx_cbdp->cbd_sc = (TX_BD_I | TX_BD_W);
+
+
+	endpoints[epid]->tptr = endpoints[epid]->tbase;
+	endpoints[epid]->tstate = 0x00;
+	endpoints[epid]->tbcnt = 0x00;
+
+	/* TX start */
+	immr->im_cpm.cp_cpcr = ((epid << 2) | 0x2D01);
+	__asm__ ("eieio");
+	while (immr->im_cpm.cp_cpcr & 0x01);
+
+	return;
+}
+
+/* mpc8xx_udc_flush_rx_fifo
+ *
+ * For the sake of completeness of the namespace, it seems like
+ * a good-design-decision (tm) to include mpc8xx_udc_flush_rx_fifo();
+ * If RX_BD_E is true => a driver bug either here or in an upper layer
+ * not polling frequently enough. If RX_BD_E is true we have told the host
+ * we have accepted data but, the CPM found it had no-where to put that data
+ * which needless to say would be a bad thing.
+ */
+static void mpc8xx_udc_flush_rx_fifo ()
+{
+	int i = 0;
+
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		if (!(rx_cbd[i]->cbd_sc & RX_BD_E)) {
+			ERR ("buf %p used rx data len = 0x%x sc=0x%x!\n",
+			     rx_cbd[i], rx_cbd[i]->cbd_datlen,
+			     rx_cbd[i]->cbd_sc);
+
+		}
+	}
+	ERR ("BUG : Input over-run\n");
+}
+
+/* mpc8xx_udc_clear_rxbd
+ *
+ * Release control of RX CBD to CP.
+ */
+static void mpc8xx_udc_clear_rxbd (volatile cbd_t * rx_cbdp)
+{
+	rx_cbdp->cbd_datlen = 0x0000;
+	rx_cbdp->cbd_sc = ((rx_cbdp->cbd_sc & RX_BD_W) | (RX_BD_E | RX_BD_I));
+	__asm__ ("eieio");
+}
+
+/* mpc8xx_udc_tx_irq
+ *
+ * Parse for tx timeout, control RX or USB reset/busy conditions
+ * Return -1 on timeout, -2 on fatal error, else return zero
+ */
+static int mpc8xx_udc_tx_irq (int ep)
+{
+	int i = 0;
+
+	if (usbp->usber & (USB_TX_ERRMASK)) {
+		if (mpc8xx_udc_handle_txerr ()) {
+			/* Timeout, controlling function must retry send */
+			return -1;
+		}
+	}
+
+	if (usbp->usber & (USB_E_RESET | USB_E_BSY)) {
+		/* Fatal, abandon TX transaction */
+		return -2;
+	}
+
+	if (usbp->usber & USB_E_RXB) {
+		for (i = 0; i < RX_RING_SIZE; i++) {
+			if (!(rx_cbd[i]->cbd_sc & RX_BD_E)) {
+				if ((rx_cbd[i] == ep_ref[0].prx) || ep) {
+					return -2;
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+/* mpc8xx_udc_ep_tx
+ *
+ * Transmit in a re-entrant fashion outbound USB packets.
+ * Implement retry/timeout mechanism described in USB specification
+ * Toggle DATA0/DATA1 pids as necessary
+ * Introduces non-standard tx_retry. The USB standard has no scope for slave
+ * devices to give up TX, however tx_retry stops us getting stuck in an endless
+ * TX loop.
+ */
+static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi)
+{
+	struct urb *urb = epi->tx_urb;
+	volatile cbd_t *tx_cbdp = 0;
+	unsigned int ep = 0, pkt_len = 0, x = 0, tx_retry = 0;
+	int ret = 0;
+
+	if (!epi || (epi->endpoint_address & 0x03) >= MAX_ENDPOINTS || !urb) {
+		return -1;
+	}
+
+	ep = epi->endpoint_address & 0x03;
+	tx_cbdp = (cbd_t *) (endpoints[ep]->tbptr + CFG_IMMR);
+
+	if (tx_cbdp->cbd_sc & TX_BD_R || usbp->usber & USB_E_TXB) {
+		mpc8xx_udc_flush_tx_fifo (ep);
+		usbp->usber |= USB_E_TXB;
+	};
+
+	while (tx_retry++ < 100) {
+		ret = mpc8xx_udc_tx_irq (ep);
+		if (ret == -1) {
+			/* ignore timeout here */
+		} else if (ret == -2) {
+			/* Abandon TX */
+			mpc8xx_udc_flush_tx_fifo (ep);
+			return -1;
+		}
+
+		tx_cbdp = (cbd_t *) (endpoints[ep]->tbptr + CFG_IMMR);
+		while (tx_cbdp->cbd_sc & TX_BD_R) {
+		};
+		tx_cbdp->cbd_sc = (tx_cbdp->cbd_sc & TX_BD_W);
+
+		pkt_len = urb->actual_length - epi->sent;
+
+		if (pkt_len > epi->tx_packetSize || pkt_len > EP_MAX_PKT) {
+			pkt_len = MIN (epi->tx_packetSize, EP_MAX_PKT);
+		}
+
+		for (x = 0; x < pkt_len; x++) {
+			*((unsigned char *) (tx_cbdp->cbd_bufaddr + x)) =
+				urb->buffer[epi->sent + x];
+		}
+		tx_cbdp->cbd_datlen = pkt_len;
+		tx_cbdp->cbd_sc |= (CBD_TX_BITMASK | ep_ref[ep].pid);
+		__asm__ ("eieio");
+
+#ifdef __SIMULATE_ERROR__
+		if (++err_poison_test == 2) {
+			err_poison_test = 0;
+			tx_cbdp->cbd_sc &= ~TX_BD_TC;
+		}
+#endif
+
+		usbp->uscom = (USCOM_STR | ep);
+
+		while (!(usbp->usber & USB_E_TXB)) {
+			ret = mpc8xx_udc_tx_irq (ep);
+			if (ret == -1) {
+				/* TX timeout */
+				break;
+			} else if (ret == -2) {
+				if (usbp->usber & USB_E_TXB) {
+					usbp->usber |= USB_E_TXB;
+				}
+				mpc8xx_udc_flush_tx_fifo (ep);
+				return -1;
+			}
+		};
+
+		if (usbp->usber & USB_E_TXB) {
+			usbp->usber |= USB_E_TXB;
+		}
+
+		/* ACK must be present <= 18bit times from TX */
+		if (ret == -1) {
+			continue;
+		}
+
+		/* TX ACK : USB 2.0 8.7.2, Toggle PID, Advance TX */
+		epi->sent += pkt_len;
+		epi->last = MIN (urb->actual_length - epi->sent, epi->tx_packetSize);
+		TOGGLE_TX_PID (ep_ref[ep].pid);
+
+		if (epi->sent >= epi->tx_urb->actual_length) {
+
+			epi->tx_urb->actual_length = 0;
+			epi->sent = 0;
+
+			if (ep_ref[ep].sc & EP_SEND_ZLP) {
+				ep_ref[ep].sc &= ~EP_SEND_ZLP;
+			} else {
+				return 0;
+			}
+		}
+	}
+
+	ERR ("TX fail, endpoint 0x%x tx bytes 0x%x/0x%x\n", ep, epi->sent,
+	     epi->tx_urb->actual_length);
+
+	return -1;
+}
+
+/* mpc8xx_udc_dump_request
+ *
+ * Dump a control request to console
+ */
+static void mpc8xx_udc_dump_request (struct usb_device_request *request)
+{
+	DBG ("bmRequestType:%02x bRequest:%02x wValue:%04x "
+	     "wIndex:%04x wLength:%04x ?\n",
+	     request->bmRequestType,
+	     request->bRequest,
+	     request->wValue, request->wIndex, request->wLength);
+
+	return;
+}
+
+/* mpc8xx_udc_ep0_rx_setup
+ *
+ * Decode received ep0 SETUP packet. return non-zero on error
+ */
+static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp)
+{
+	unsigned int x = 0;
+	struct urb *purb = ep_ref[0].urb;
+	struct usb_endpoint_instance *epi =
+		&udc_device->bus->endpoint_array[0];
+
+	for (; x < rx_cbdp->cbd_datlen; x++) {
+		*(((unsigned char *) &ep_ref[0].urb->device_request) + x) =
+			*((unsigned char *) (rx_cbdp->cbd_bufaddr + x));
+	}
+
+	mpc8xx_udc_clear_rxbd (rx_cbdp);
+
+	if (ep0_recv_setup (purb)) {
+		mpc8xx_udc_dump_request (&purb->device_request);
+		return -1;
+	}
+
+	if ((purb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
+	    == USB_REQ_HOST2DEVICE) {
+
+		switch (purb->device_request.bRequest) {
+		case USB_REQ_SET_ADDRESS:
+			/* Send the Status OUT ZLP */
+			ep_ref[0].pid = TX_BD_PID_DATA1;
+			purb->actual_length = 0;
+			mpc8xx_udc_init_tx (epi, purb);
+			mpc8xx_udc_ep_tx (epi);
+
+			/* Move to the addressed state */
+			usbp->usaddr = udc_device->address;
+			mpc8xx_udc_state_transition_up (udc_device->device_state,
+							STATE_ADDRESSED);
+			return 0;
+
+		case USB_REQ_SET_CONFIGURATION:
+			if (!purb->device_request.wValue) {
+				/* Respond at default address */
+				usbp->usaddr = 0x00;
+				mpc8xx_udc_state_transition_down (udc_device->device_state,
+								  STATE_ADDRESSED);
+			} else {
+				/* TODO: Support multiple configurations */
+				mpc8xx_udc_state_transition_up (udc_device->device_state,
+								STATE_CONFIGURED);
+				for (x = 1; x < MAX_ENDPOINTS; x++) {
+					if ((udc_device->bus->endpoint_array[x].endpoint_address & USB_ENDPOINT_DIR_MASK)
+					    == USB_DIR_IN) {
+						ep_ref[x].pid = TX_BD_PID_DATA0;
+					} else {
+						ep_ref[x].pid = RX_BD_PID_DATA0;
+					}
+					/* Set configuration must unstall endpoints */
+					usbp->usep[x] &= ~STALL_BITMASK;
+				}
+			}
+			break;
+		default:
+			/* CDC/Vendor specific */
+			break;
+		}
+
+		/* Send ZLP as ACK in Status OUT phase */
+		ep_ref[0].pid = TX_BD_PID_DATA1;
+		purb->actual_length = 0;
+		mpc8xx_udc_init_tx (epi, purb);
+		mpc8xx_udc_ep_tx (epi);
+
+	} else {
+
+		if (purb->actual_length) {
+			ep_ref[0].pid = TX_BD_PID_DATA1;
+			mpc8xx_udc_init_tx (epi, purb);
+
+			if (!(purb->actual_length % EP0_MAX_PACKET_SIZE)) {
+				ep_ref[0].sc |= EP_SEND_ZLP;
+			}
+
+			if (purb->device_request.wValue ==
+			    USB_DESCRIPTOR_TYPE_DEVICE) {
+				if (le16_to_cpu (purb->device_request.wLength)
+				    > purb->actual_length) {
+					/* Send EP0_MAX_PACKET_SIZE bytes
+					 * unless correct size requested.
+					 */
+					if (purb->actual_length > epi->tx_packetSize) {
+						purb->actual_length = epi->tx_packetSize;
+					}
+				}
+			}
+			mpc8xx_udc_ep_tx (epi);
+
+		} else {
+			/* Corrupt SETUP packet? */
+			ERR ("Zero length data or SETUP with DATA-IN phase ?\n");
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/* mpc8xx_udc_init_tx
+ *
+ * Setup some basic parameters for a TX transaction
+ */
+static void mpc8xx_udc_init_tx (struct usb_endpoint_instance *epi,
+				struct urb *tx_urb)
+{
+	epi->sent = 0;
+	epi->last = 0;
+	epi->tx_urb = tx_urb;
+}
+
+/* mpc8xx_udc_ep0_rx
+ *
+ * Receive ep0/control USB data. Parse and possibly send a response.
+ */
+static void mpc8xx_udc_ep0_rx (volatile cbd_t * rx_cbdp)
+{
+	if (rx_cbdp->cbd_sc & RX_BD_PID_SETUP) {
+
+		/* Unconditionally accept SETUP packets */
+		if (mpc8xx_udc_ep0_rx_setup (rx_cbdp)) {
+			mpc8xx_udc_stall (0);
+		}
+
+	} else {
+
+		mpc8xx_udc_clear_rxbd (rx_cbdp);
+
+		if ((rx_cbdp->cbd_datlen - 2)) {
+			/* SETUP with a DATA phase
+			 * outside of SETUP packet.
+			 * Reply with STALL.
+			 */
+			mpc8xx_udc_stall (0);
+		}
+	}
+}
+
+/* mpc8xx_udc_epn_rx
+ *
+ * Receive some data from cbd into USB system urb data abstraction
+ * Upper layers should NAK if there is insufficient RX data space
+ */
+static int mpc8xx_udc_epn_rx (unsigned int epid, volatile cbd_t * rx_cbdp)
+{
+	struct usb_endpoint_instance *epi = 0;
+	struct urb *urb = 0;
+	unsigned int x = 0;
+
+	if (epid >= MAX_ENDPOINTS || !rx_cbdp->cbd_datlen) {
+		return 0;
+	}
+
+	/* USB 2.0 PDF section 8.6.4
+	 * Discard data with invalid PID it is a resend.
+	 */
+	if (ep_ref[epid].pid != (rx_cbdp->cbd_sc & 0xC0)) {
+		return 1;
+	}
+	TOGGLE_RX_PID (ep_ref[epid].pid);
+
+	epi = &udc_device->bus->endpoint_array[epid];
+	urb = epi->rcv_urb;
+
+	for (; x < (rx_cbdp->cbd_datlen - 2); x++) {
+		*((unsigned char *) (urb->buffer + urb->actual_length + x)) =
+			*((unsigned char *) (rx_cbdp->cbd_bufaddr + x));
+	}
+
+	if (x) {
+		usbd_rcv_complete (epi, x, 0);
+		if (ep_ref[epid].urb->status == RECV_ERROR) {
+			DBG ("RX error unset NAK\n");
+			udc_unset_nak (epid);
+		}
+	}
+	return x;
+}
+
+/* mpc8xx_udc_clock_init
+ *
+ * Obtain a clock reference for Full Speed Signaling
+ */
+static void mpc8xx_udc_clock_init (volatile immap_t * immr,
+				   volatile cpm8xx_t * cp)
+{
+
+#if defined(CFG_USB_EXTC_CLK)
+
+	/* This has been tested with a 48MHz crystal on CLK6 */
+	switch (CFG_USB_EXTC_CLK) {
+	case 1:
+		immr->im_ioport.iop_papar |= 0x0100;
+		immr->im_ioport.iop_padir &= ~0x0100;
+		cp->cp_sicr |= 0x24;
+		break;
+	case 2:
+		immr->im_ioport.iop_papar |= 0x0200;
+		immr->im_ioport.iop_padir &= ~0x0200;
+		cp->cp_sicr |= 0x2D;
+		break;
+	case 3:
+		immr->im_ioport.iop_papar |= 0x0400;
+		immr->im_ioport.iop_padir &= ~0x0400;
+		cp->cp_sicr |= 0x36;
+		break;
+	case 4:
+		immr->im_ioport.iop_papar |= 0x0800;
+		immr->im_ioport.iop_padir &= ~0x0800;
+		cp->cp_sicr |= 0x3F;
+		break;
+	default:
+		udc_state = STATE_ERROR;
+		break;
+	}
+
+#elif defined(CFG_USB_BRGCLK)
+
+	/* This has been tested with brgclk == 50MHz */
+	DECLARE_GLOBAL_DATA_PTR;
+	int divisor = 0;
+
+	if (gd->cpu_clk < 48000000L) {
+		ERR ("brgclk is too slow for full-speed USB!\n");
+		udc_state = STATE_ERROR;
+		return;
+	}
+
+	/* Assume the brgclk is 'good enough', we want !(gd->cpu_clk%48Mhz)
+	 * but, can /probably/ live with close-ish alternative rates.
+	 */
+	divisor = (gd->cpu_clk / 48000000L) - 1;
+	cp->cp_sicr &= ~0x0000003F;
+
+	switch (CFG_USB_BRGCLK) {
+	case 1:
+		cp->cp_brgc1 |= (divisor | CPM_BRG_EN);
+		cp->cp_sicr &= ~0x2F;
+		break;
+	case 2:
+		cp->cp_brgc2 |= (divisor | CPM_BRG_EN);
+		cp->cp_sicr |= 0x00000009;
+		break;
+	case 3:
+		cp->cp_brgc3 |= (divisor | CPM_BRG_EN);
+		cp->cp_sicr |= 0x00000012;
+		break;
+	case 4:
+		cp->cp_brgc4 = (divisor | CPM_BRG_EN);
+		cp->cp_sicr |= 0x0000001B;
+		break;
+	default:
+		udc_state = STATE_ERROR;
+		break;
+	}
+
+#else
+#error "CFG_USB_EXTC_CLK or CFG_USB_BRGCLK must be defined"
+#endif
+
+}
+
+/* mpc8xx_udc_cbd_attach
+ *
+ * attach a cbd to and endpoint
+ */
+static void mpc8xx_udc_cbd_attach (int ep, uchar tx_size, uchar rx_size)
+{
+
+	if (!tx_cbd[ep] || !rx_cbd[ep] || ep >= MAX_ENDPOINTS) {
+		udc_state = STATE_ERROR;
+		return;
+	}
+
+	if (tx_size > USB_MAX_PKT || rx_size > USB_MAX_PKT ||
+	    (!tx_size && !rx_size)) {
+		udc_state = STATE_ERROR;
+		return;
+	}
+
+	/* Attach CBD to appropiate Parameter RAM Endpoint data structure */
+	if (rx_size) {
+		endpoints[ep]->rbase = (u32) rx_cbd[rx_ct];
+		endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
+		rx_ct++;
+
+		if (!ep) {
+
+			endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
+			rx_cbd[rx_ct]->cbd_sc |= RX_BD_W;
+			rx_ct++;
+
+		} else {
+			rx_ct += 2;
+			endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
+			rx_cbd[rx_ct]->cbd_sc |= RX_BD_W;
+			rx_ct++;
+		}
+
+		/* Where we expect to RX data on this endpoint */
+		ep_ref[ep].prx = rx_cbd[rx_ct - 1];
+	} else {
+
+		ep_ref[ep].prx = 0;
+		endpoints[ep]->rbase = 0;
+		endpoints[ep]->rbptr = 0;
+	}
+
+	if (tx_size) {
+		endpoints[ep]->tbase = (u32) tx_cbd[tx_ct];
+		endpoints[ep]->tbptr = (u32) tx_cbd[tx_ct];
+		tx_ct++;
+	} else {
+		endpoints[ep]->tbase = 0;
+		endpoints[ep]->tbptr = 0;
+	}
+
+	endpoints[ep]->tstate = 0;
+	endpoints[ep]->tbcnt = 0;
+	endpoints[ep]->mrblr = EP_MAX_PKT;
+	endpoints[ep]->rfcr = 0x18;
+	endpoints[ep]->tfcr = 0x18;
+	ep_ref[ep].sc |= EP_ATTACHED;
+
+	DBG ("ep %d rbase 0x%08x rbptr 0x%08x tbase 0x%08x tbptr 0x%08x prx = %p\n",
+		ep, endpoints[ep]->rbase, endpoints[ep]->rbptr,
+		endpoints[ep]->tbase, endpoints[ep]->tbptr,
+		ep_ref[ep].prx);
+
+	return;
+}
+
+/* mpc8xx_udc_cbd_init
+ *
+ * Allocate space for a cbd and allocate TX/RX data space
+ */
+static void mpc8xx_udc_cbd_init (void)
+{
+	int i = 0;
+
+	for (; i < TX_RING_SIZE; i++) {
+		tx_cbd[i] = (cbd_t *)
+			mpc8xx_udc_alloc (sizeof (cbd_t), sizeof (int));
+	}
+
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		rx_cbd[i] = (cbd_t *)
+			mpc8xx_udc_alloc (sizeof (cbd_t), sizeof (int));
+	}
+
+	for (i = 0; i < TX_RING_SIZE; i++) {
+		tx_cbd[i]->cbd_bufaddr =
+			mpc8xx_udc_alloc (EP_MAX_PKT, sizeof (int));
+
+		tx_cbd[i]->cbd_sc = (TX_BD_I | TX_BD_W);
+		tx_cbd[i]->cbd_datlen = 0x0000;
+	}
+
+
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		rx_cbd[i]->cbd_bufaddr =
+			mpc8xx_udc_alloc (EP_MAX_PKT, sizeof (int));
+		rx_cbd[i]->cbd_sc = (RX_BD_I | RX_BD_E);
+		rx_cbd[i]->cbd_datlen = 0x0000;
+
+	}
+
+	return;
+}
+
+/* mpc8xx_udc_endpoint_init
+ *
+ * Attach an endpoint to some dpram
+ */
+static void mpc8xx_udc_endpoint_init (void)
+{
+	int i = 0;
+
+	for (; i < MAX_ENDPOINTS; i++) {
+		endpoints[i] = (usb_epb_t *)
+			mpc8xx_udc_alloc (sizeof (usb_epb_t), 32);
+	}
+}
+
+/* mpc8xx_udc_alloc
+ *
+ * Grab the address of some dpram
+ */
+static u32 mpc8xx_udc_alloc (u32 data_size, u32 alignment)
+{
+	u32 retaddr = address_base;
+
+	while (retaddr % alignment) {
+		retaddr++;
+	}
+	address_base += data_size;
+
+	return retaddr;
+}
+
+#endif /* CONFIG_MPC885_FAMILY && CONFIG_USB_DEVICE) */
diff --git a/drivers/usbdcore_omap1510.c b/drivers/usbdcore_omap1510.c
index 1d54a635755ad3185f0c79e1134c43ff8ef5329c..84bb936d86923edd3275fd3891172f3991db0603 100644
--- a/drivers/usbdcore_omap1510.c
+++ b/drivers/usbdcore_omap1510.c
@@ -1517,4 +1517,31 @@ void udc_startup_events (struct usb_device_instance *device)
 	udc_enable (device);
 }
 
+/**
+ * udc_irq - do pseudo interrupts
+ */
+void udc_irq(void)
+{
+	/* Loop while we have interrupts.
+	 * If we don't do this, the input chain
+	 * polling delay is likely to miss
+	 * host requests.
+	 */
+	while (inw (UDC_IRQ_SRC) & ~UDC_SOF_Flg) {
+		/* Handle any new IRQs */
+		omap1510_udc_irq ();
+		omap1510_udc_noniso_irq ();
+	}
+}
+
+/* Flow control */
+void udc_set_nak(int epid)
+{
+	/* TODO: implement this functionality in omap1510 */
+}
+
+void udc_unset_nak (int epid)
+{
+	/* TODO: implement this functionality in omap1510 */
+}
 #endif
diff --git a/drivers/usbtty.c b/drivers/usbtty.c
index ce4a12e16e0eb7e0eb307a086a1014c327db0f80..a3b50131dfc1bc47c20f58a3927364e6dd12c6f3 100644
--- a/drivers/usbtty.c
+++ b/drivers/usbtty.c
@@ -2,6 +2,9 @@
  * (C) Copyright 2003
  * Gerry Hamel, geh@ti.com, Texas Instruments
  *
+ * (C) Copyright 2006
+ * Bryan O'Donoghue, bodonoghue@codehermit.ie
+ *
  * 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
@@ -25,19 +28,41 @@
 #include <circbuf.h>
 #include <devices.h>
 #include "usbtty.h"
+#include "usb_cdc_acm.h"
+#include "usbdescriptors.h"
+#include <config.h>		/* If defined, override Linux identifiers with
+			   	 * vendor specific ones */
 
 #if 0
-#define TTYDBG(fmt,args...) serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args)
+#define TTYDBG(fmt,args...)\
+	serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args)
 #else
 #define TTYDBG(fmt,args...) do{}while(0)
 #endif
 
-#if 0
-#define TTYERR(fmt,args...) serial_printf("ERROR![%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args)
+#if 1
+#define TTYERR(fmt,args...)\
+	serial_printf("ERROR![%s] %s %d: "fmt, __FILE__,__FUNCTION__,\
+	__LINE__,##args)
 #else
 #define TTYERR(fmt,args...) do{}while(0)
 #endif
 
+/*
+ * Defines
+ */
+#define NUM_CONFIGS    1
+#define MAX_INTERFACES 2
+#define NUM_ENDPOINTS  3
+#define ACM_TX_ENDPOINT 3
+#define ACM_RX_ENDPOINT 2
+#define GSERIAL_TX_ENDPOINT 2
+#define GSERIAL_RX_ENDPOINT 1
+#define NUM_ACM_INTERFACES 2
+#define NUM_GSERIAL_INTERFACES 1
+#define CONFIG_USBD_DATA_INTERFACE_STR "Bulk Data Interface"
+#define CONFIG_USBD_CTRL_INTERFACE_STR "Control Interface"
+
 /*
  * Buffers to hold input and output data
  */
@@ -50,157 +75,336 @@ static circbuf_t usbtty_output;
  * Instance variables
  */
 static device_t usbttydev;
-static struct usb_device_instance	 device_instance[1];
-static struct usb_bus_instance		 bus_instance[1];
+static struct usb_device_instance device_instance[1];
+static struct usb_bus_instance bus_instance[1];
 static struct usb_configuration_instance config_instance[NUM_CONFIGS];
-static struct usb_interface_instance	 interface_instance[NUM_INTERFACES];
-static struct usb_alternate_instance	 alternate_instance[NUM_INTERFACES];
-static struct usb_endpoint_instance	 endpoint_instance[NUM_ENDPOINTS+1]; /* one extra for control endpoint */
-
-/*
- * Static allocation of urbs
- */
-#define RECV_ENDPOINT 1
-#define TX_ENDPOINT 2
+static struct usb_interface_instance interface_instance[MAX_INTERFACES];
+static struct usb_alternate_instance alternate_instance[MAX_INTERFACES];
+/* one extra for control endpoint */
+static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1];
 
 /*
  * Global flag
  */
 int usbtty_configured_flag = 0;
 
-
 /*
  * Serial number
  */
 static char serial_number[16];
 
+
 /*
- * Descriptors
+ * Descriptors, Strings, Local variables.
  */
+
+/* defined and used by usbdcore_ep0.c */
+extern struct usb_string_descriptor **usb_strings;
+
+/* Indicies, References */
+static unsigned short rx_endpoint = 0;
+static unsigned short tx_endpoint = 0;
+static unsigned short interface_count = 0;
+static struct usb_string_descriptor *usbtty_string_table[STR_COUNT];
+
+/* USB Descriptor Strings */
 static u8 wstrLang[4] = {4,USB_DT_STRING,0x9,0x4};
 static u8 wstrManufacturer[2 + 2*(sizeof(CONFIG_USBD_MANUFACTURER)-1)];
 static u8 wstrProduct[2 + 2*(sizeof(CONFIG_USBD_PRODUCT_NAME)-1)];
 static u8 wstrSerial[2 + 2*(sizeof(serial_number) - 1)];
 static u8 wstrConfiguration[2 + 2*(sizeof(CONFIG_USBD_CONFIGURATION_STR)-1)];
-static u8 wstrInterface[2 + 2*(sizeof(CONFIG_USBD_INTERFACE_STR)-1)];
-
-static struct usb_string_descriptor *usbtty_string_table[] = {
-  (struct usb_string_descriptor*)wstrLang,
-  (struct usb_string_descriptor*)wstrManufacturer,
-  (struct usb_string_descriptor*)wstrProduct,
-  (struct usb_string_descriptor*)wstrSerial,
-  (struct usb_string_descriptor*)wstrConfiguration,
-  (struct usb_string_descriptor*)wstrInterface
-};
-extern struct usb_string_descriptor **usb_strings; /* defined and used by omap1510_ep0.c */
+static u8 wstrDataInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];
+static u8 wstrCtrlInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];
 
+/* Standard USB Data Structures */
+static struct usb_interface_descriptor interface_descriptors[MAX_INTERFACES];
+static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS];
+static struct usb_configuration_descriptor	*configuration_descriptor = 0;
 static struct usb_device_descriptor device_descriptor = {
-  bLength:	      sizeof(struct usb_device_descriptor),
-  bDescriptorType:    USB_DT_DEVICE,
-  bcdUSB:	      USB_BCD_VERSION,
-  bDeviceClass:	      USBTTY_DEVICE_CLASS,
-  bDeviceSubClass:    USBTTY_DEVICE_SUBCLASS,
-  bDeviceProtocol:    USBTTY_DEVICE_PROTOCOL,
-  bMaxPacketSize0:    EP0_MAX_PACKET_SIZE,
-  idVendor:	      CONFIG_USBD_VENDORID,
-  idProduct:	      CONFIG_USBD_PRODUCTID,
-  bcdDevice:	      USBTTY_BCD_DEVICE,
-  iManufacturer:      STR_MANUFACTURER,
-  iProduct:	      STR_PRODUCT,
-  iSerialNumber:      STR_SERIAL,
-  bNumConfigurations: NUM_CONFIGS
-  };
-static struct usb_configuration_descriptor config_descriptors[NUM_CONFIGS] = {
-  {
-    bLength:		 sizeof(struct usb_configuration_descriptor),
-    bDescriptorType:	 USB_DT_CONFIG,
-    wTotalLength:	 (sizeof(struct usb_configuration_descriptor)*NUM_CONFIGS) +
-			 (sizeof(struct usb_interface_descriptor)*NUM_INTERFACES) +
-			 (sizeof(struct usb_endpoint_descriptor)*NUM_ENDPOINTS),
-    bNumInterfaces:	 NUM_INTERFACES,
-    bConfigurationValue: 1,
-    iConfiguration:	 STR_CONFIG,
-    bmAttributes:	 BMATTRIBUTE_SELF_POWERED | BMATTRIBUTE_RESERVED,
-    bMaxPower:		 USBTTY_MAXPOWER
-  },
-};
-static struct usb_interface_descriptor interface_descriptors[NUM_INTERFACES] = {
-  {
-    bLength:		 sizeof(struct usb_interface_descriptor),
-    bDescriptorType:	 USB_DT_INTERFACE,
-    bInterfaceNumber:	 0,
-    bAlternateSetting:	 0,
-    bNumEndpoints:	 NUM_ENDPOINTS,
-    bInterfaceClass:	 USBTTY_INTERFACE_CLASS,
-    bInterfaceSubClass:	 USBTTY_INTERFACE_SUBCLASS,
-    bInterfaceProtocol:	 USBTTY_INTERFACE_PROTOCOL,
-    iInterface:		 STR_INTERFACE
-  },
+	.bLength = sizeof(struct usb_device_descriptor),
+	.bDescriptorType =	USB_DT_DEVICE,
+	.bcdUSB = 		cpu_to_le16(USB_BCD_VERSION),
+	.bDeviceSubClass =	0x00,
+	.bDeviceProtocol =	0x00,
+	.bMaxPacketSize0 =	EP0_MAX_PACKET_SIZE,
+	.idVendor =		cpu_to_le16(CONFIG_USBD_VENDORID),
+	.bcdDevice =		cpu_to_le16(USBTTY_BCD_DEVICE),
+	.iManufacturer =	STR_MANUFACTURER,
+	.iProduct =		STR_PRODUCT,
+	.iSerialNumber =	STR_SERIAL,
+	.bNumConfigurations =	NUM_CONFIGS
 };
-static struct usb_endpoint_descriptor ep_descriptors[NUM_ENDPOINTS] = {
-  {
-    bLength:		 sizeof(struct usb_endpoint_descriptor),
-    bDescriptorType:	 USB_DT_ENDPOINT,
-    bEndpointAddress:	 CONFIG_USBD_SERIAL_OUT_ENDPOINT | USB_DIR_OUT,
-    bmAttributes:	 USB_ENDPOINT_XFER_BULK,
-    wMaxPacketSize:	 CONFIG_USBD_SERIAL_OUT_PKTSIZE,
-    bInterval:		 0
-  },
-  {
-    bLength:		 sizeof(struct usb_endpoint_descriptor),
-    bDescriptorType:	 USB_DT_ENDPOINT,
-    bEndpointAddress:	 CONFIG_USBD_SERIAL_IN_ENDPOINT | USB_DIR_IN,
-    bmAttributes:	 USB_ENDPOINT_XFER_BULK,
-    wMaxPacketSize:	 CONFIG_USBD_SERIAL_IN_PKTSIZE,
-    bInterval:		 0
-  },
-  {
-    bLength:		 sizeof(struct usb_endpoint_descriptor),
-    bDescriptorType:	 USB_DT_ENDPOINT,
-    bEndpointAddress:	 CONFIG_USBD_SERIAL_INT_ENDPOINT | USB_DIR_IN,
-    bmAttributes:	 USB_ENDPOINT_XFER_INT,
-    wMaxPacketSize:	 CONFIG_USBD_SERIAL_INT_PKTSIZE,
-    bInterval:		 0
-  },
+
+
+/*
+ * Static CDC ACM specific descriptors
+ */
+
+struct acm_config_desc {
+	struct usb_configuration_descriptor configuration_desc;
+
+	/* Master Interface */
+	struct usb_interface_descriptor interface_desc;
+
+	struct usb_class_header_function_descriptor usb_class_header;
+	struct usb_class_call_management_descriptor usb_class_call_mgt;
+	struct usb_class_abstract_control_descriptor usb_class_acm;
+	struct usb_class_union_function_descriptor usb_class_union;
+	struct usb_endpoint_descriptor notification_endpoint;
+
+	/* Slave Interface */
+	struct usb_interface_descriptor data_class_interface;
+	struct usb_endpoint_descriptor
+		data_endpoints[NUM_ENDPOINTS-1] __attribute__((packed));
+} __attribute__((packed));
+
+static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {
+	{
+		.configuration_desc ={
+			.bLength =
+				sizeof(struct usb_configuration_descriptor),
+    			.bDescriptorType = USB_DT_CONFIG,
+			.wTotalLength =
+				cpu_to_le16(sizeof(struct acm_config_desc)),
+	    		.bNumInterfaces = NUM_ACM_INTERFACES,
+    			.bConfigurationValue = 1,
+			.iConfiguration = STR_CONFIG,
+			.bmAttributes =
+				BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
+			.bMaxPower = USBTTY_MAXPOWER
+		},
+		/* Interface 1 */
+		.interface_desc = {
+			.bLength  = sizeof(struct usb_interface_descriptor),
+			.bDescriptorType = USB_DT_INTERFACE,
+			.bInterfaceNumber = 0,
+			.bAlternateSetting = 0,
+			.bNumEndpoints = 0x01,
+			.bInterfaceClass =
+				COMMUNICATIONS_INTERFACE_CLASS_CONTROL,
+			.bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS,
+			.bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL,
+			.iInterface = STR_CTRL_INTERFACE,
+		},
+		.usb_class_header = {
+			.bFunctionLength	=
+				sizeof(struct usb_class_header_function_descriptor),
+			.bDescriptorType	= CS_INTERFACE,
+			.bDescriptorSubtype	= USB_ST_HEADER,
+			.bcdCDC	= cpu_to_le16(110),
+		},
+		.usb_class_call_mgt = {
+			.bFunctionLength	=
+				sizeof(struct usb_class_call_management_descriptor),
+			.bDescriptorType	= CS_INTERFACE,
+			.bDescriptorSubtype	= USB_ST_CMF,
+			.bmCapabilities		= 0x00,
+			.bDataInterface		= 0x01,
+		},
+		.usb_class_acm = {
+			.bFunctionLength	=
+				sizeof(struct usb_class_abstract_control_descriptor),
+			.bDescriptorType	= CS_INTERFACE,
+			.bDescriptorSubtype	= USB_ST_ACMF,
+			.bmCapabilities		= 0x00,
+		},
+		.usb_class_union = {
+			.bFunctionLength	=
+				sizeof(struct usb_class_union_function_descriptor),
+			.bDescriptorType	= CS_INTERFACE,
+			.bDescriptorSubtype	= USB_ST_UF,
+			.bMasterInterface	= 0x00,
+			.bSlaveInterface0	= 0x01,
+		},
+		.notification_endpoint = {
+			.bLength =
+				sizeof(struct usb_endpoint_descriptor),
+			.bDescriptorType	= USB_DT_ENDPOINT,
+			.bEndpointAddress	= 0x01 | USB_DIR_IN,
+			.bmAttributes		= USB_ENDPOINT_XFER_INT,
+			.wMaxPacketSize
+				= cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
+			.bInterval		= 0xFF,
+		},
+
+		/* Interface 2 */
+		.data_class_interface = {
+			.bLength		=
+				sizeof(struct usb_interface_descriptor),
+			.bDescriptorType	= USB_DT_INTERFACE,
+			.bInterfaceNumber	= 0x01,
+			.bAlternateSetting	= 0x00,
+			.bNumEndpoints		= 0x02,
+			.bInterfaceClass	=
+				COMMUNICATIONS_INTERFACE_CLASS_DATA,
+			.bInterfaceSubClass	= DATA_INTERFACE_SUBCLASS_NONE,
+			.bInterfaceProtocol	= DATA_INTERFACE_PROTOCOL_NONE,
+			.iInterface		= STR_DATA_INTERFACE,
+		},
+		.data_endpoints = {
+			{
+				.bLength		=
+					sizeof(struct usb_endpoint_descriptor),
+				.bDescriptorType	= USB_DT_ENDPOINT,
+				.bEndpointAddress	= 0x02 | USB_DIR_OUT,
+				.bmAttributes		=
+					USB_ENDPOINT_XFER_BULK,
+				.wMaxPacketSize		=
+					cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
+				.bInterval		= 0xFF,
+			},
+			{
+				.bLength		=
+					sizeof(struct usb_endpoint_descriptor),
+				.bDescriptorType	= USB_DT_ENDPOINT,
+				.bEndpointAddress	= 0x03 | USB_DIR_IN,
+				.bmAttributes		=
+					USB_ENDPOINT_XFER_BULK,
+				.wMaxPacketSize		=
+					cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
+				.bInterval		= 0xFF,
+			},
+		},
+	},
 };
-static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS] = {
-  &(ep_descriptors[0]),
-  &(ep_descriptors[1]),
-  &(ep_descriptors[2]),
+
+static struct rs232_emu rs232_desc={
+		.dter 		=  	115200,
+	   	.stop_bits	=	0x00,
+	   	.parity		=	0x00,
+		.data_bits	=	0x08
 };
 
-/* utility function for converting char* to wide string used by USB */
-static void str2wide (char *str, u16 * wide)
-{
-	int i;
 
-	for (i = 0; i < strlen (str) && str[i]; i++)
-		wide[i] = (u16) str[i];
-}
+/*
+ * Static Generic Serial specific data
+ */
+
+
+struct gserial_config_desc {
+
+	struct usb_configuration_descriptor configuration_desc;
+	struct usb_interface_descriptor
+		interface_desc[NUM_GSERIAL_INTERFACES] __attribute__((packed));
+	struct usb_endpoint_descriptor
+		data_endpoints[NUM_ENDPOINTS] __attribute__((packed));
+
+} __attribute__((packed));
+
+static struct gserial_config_desc
+gserial_configuration_descriptors[NUM_CONFIGS] ={
+	{
+		.configuration_desc ={
+			.bLength = sizeof(struct usb_configuration_descriptor),
+			.bDescriptorType = USB_DT_CONFIG,
+			.wTotalLength =
+				cpu_to_le16(sizeof(struct gserial_config_desc)),
+			.bNumInterfaces = NUM_GSERIAL_INTERFACES,
+			.bConfigurationValue = 1,
+			.iConfiguration = STR_CONFIG,
+			.bmAttributes =
+				BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
+			.bMaxPower = USBTTY_MAXPOWER
+		},
+		.interface_desc = {
+			{
+				.bLength  =
+					sizeof(struct usb_interface_descriptor),
+				.bDescriptorType = USB_DT_INTERFACE,
+				.bInterfaceNumber = 0,
+				.bAlternateSetting = 0,
+				.bNumEndpoints = NUM_ENDPOINTS,
+				.bInterfaceClass =
+					COMMUNICATIONS_INTERFACE_CLASS_VENDOR,
+				.bInterfaceSubClass =
+					COMMUNICATIONS_NO_SUBCLASS,
+				.bInterfaceProtocol =
+					COMMUNICATIONS_NO_PROTOCOL,
+				.iInterface = STR_DATA_INTERFACE
+			},
+  		},
+		.data_endpoints  = {
+			{
+				.bLength =
+					sizeof(struct usb_endpoint_descriptor),
+				.bDescriptorType =	USB_DT_ENDPOINT,
+				.bEndpointAddress =	0x01 | USB_DIR_OUT,
+				.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+				.wMaxPacketSize =
+					cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE),
+				.bInterval=		0xFF,
+			},
+			{
+				.bLength =
+					sizeof(struct usb_endpoint_descriptor),
+				.bDescriptorType =	USB_DT_ENDPOINT,
+				.bEndpointAddress =	0x02 | USB_DIR_IN,
+				.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+				.wMaxPacketSize =
+					cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE),
+				.bInterval = 		0xFF,
+			},
+			{
+				.bLength =
+					sizeof(struct usb_endpoint_descriptor),
+				.bDescriptorType =	USB_DT_ENDPOINT,
+				.bEndpointAddress =	0x03 | USB_DIR_IN,
+				.bmAttributes =		USB_ENDPOINT_XFER_INT,
+    				.wMaxPacketSize =
+					cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
+				.bInterval =		0xFF,
+			},
+		},
+	},
+};
 
 /*
- * Prototypes
+ * Static Function Prototypes
  */
+
 static void usbtty_init_strings (void);
 static void usbtty_init_instances (void);
 static void usbtty_init_endpoints (void);
-
+static void usbtty_init_terminal_type(short type);
 static void usbtty_event_handler (struct usb_device_instance *device,
-				  usb_device_event_t event, int data);
+				usb_device_event_t event, int data);
+static int usbtty_cdc_setup(struct usb_device_request *request,
+				struct urb *urb);
 static int usbtty_configured (void);
-
 static int write_buffer (circbuf_t * buf);
 static int fill_buffer (circbuf_t * buf);
 
 void usbtty_poll (void);
-static void pretend_interrupts (void);
 
+/* utility function for converting char* to wide string used by USB */
+static void str2wide (char *str, u16 * wide)
+{
+	int i;
+	for (i = 0; i < strlen (str) && str[i]; i++){
+		#if defined(__LITTLE_ENDIAN)
+			wide[i] = (u16) str[i];
+		#elif defined(__BIG_ENDIAN)
+			wide[i] = ((u16)(str[i])<<8);
+		#else
+			#error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined"
+		#endif
+	}
+}
 
 /*
  * Test whether a character is in the RX buffer
  */
+
 int usbtty_tstc (void)
 {
+	struct usb_endpoint_instance *endpoint =
+		&endpoint_instance[rx_endpoint];
+
+	/* If no input data exists, allow more RX to be accepted */
+	if(usbtty_input.size <= 0){
+		udc_unset_nak(endpoint->endpoint_address&0x03);
+	}
+
 	usbtty_poll ();
 	return (usbtty_input.size > 0);
 }
@@ -210,15 +414,21 @@ int usbtty_tstc (void)
  * otherwise. When the function is succesfull, the character read is
  * written into its argument c.
  */
+
 int usbtty_getc (void)
 {
 	char c;
+	struct usb_endpoint_instance *endpoint =
+		&endpoint_instance[rx_endpoint];
 
 	while (usbtty_input.size <= 0) {
+		udc_unset_nak(endpoint->endpoint_address&0x03);
 		usbtty_poll ();
 	}
 
 	buf_pop (&usbtty_input, &c, 1);
+	udc_set_nak(endpoint->endpoint_address&0x03);
+
 	return c;
 }
 
@@ -238,7 +448,6 @@ void usbtty_putc (const char c)
 	}
 }
 
-
 /* usbtty_puts() helper function for finding the next '\n' in a string */
 static int next_nl_pos (const char *s)
 {
@@ -252,8 +461,9 @@ static int next_nl_pos (const char *s)
 }
 
 /*
- * Output a string to the usb client port.
+ * Output a string to the usb client port - implementing flow control
  */
+
 static void __usbtty_puts (const char *str, int len)
 {
 	int maxlen = usbtty_output.totalsize;
@@ -261,22 +471,19 @@ static void __usbtty_puts (const char *str, int len)
 
 	/* break str into chunks < buffer size, if needed */
 	while (len > 0) {
-		space = maxlen - usbtty_output.size;
+		usbtty_poll ();
 
+		space = maxlen - usbtty_output.size;
 		/* Empty buffer here, if needed, to ensure space... */
-		if (space <= 0) {
+		if (space) {
 			write_buffer (&usbtty_output);
-			space = maxlen - usbtty_output.size;
-			if (space <= 0) {
-				space = len;	/* allow old data to be overwritten. */
-			}
-		}
 
-		n = MIN (space, MIN (len, maxlen));
-		buf_push (&usbtty_output, str, n);
+			n = MIN (space, MIN (len, maxlen));
+			buf_push (&usbtty_output, str, n);
 
-		str += n;
-		len -= n;
+			str += n;
+			len -= n;
+		}
 	}
 }
 
@@ -313,8 +520,10 @@ int drv_usbtty_init (void)
 {
 	int rc;
 	char * sn;
+	char * tt;
 	int snlen;
 
+	/* Ger seiral number */
 	if (!(sn = getenv("serial#"))) {
 		sn = "000000000000";
 	}
@@ -327,6 +536,14 @@ int drv_usbtty_init (void)
 	memcpy (serial_number, sn, snlen);
 	serial_number[snlen] = '\0';
 
+	/* Decide on which type of UDC device to be.
+	 */
+
+	if(!(tt = getenv("usbtty"))) {
+		tt = "generic";
+	}
+	usbtty_init_terminal_type(strcmp(tt,"cdc_acm"));
+
 	/* prepare buffers... */
 	buf_init (&usbtty_input, USBTTY_BUFFER_SIZE);
 	buf_init (&usbtty_output, USBTTY_BUFFER_SIZE);
@@ -337,7 +554,7 @@ int drv_usbtty_init (void)
 	usbtty_init_strings ();
 	usbtty_init_instances ();
 
-	udc_startup_events (device_instance);	/* Enable our device, initialize udc pointers */
+	udc_startup_events (device_instance);/* Enable dev, init udc pointers */
 	udc_connect ();		/* Enable pullup for host detection */
 
 	usbtty_init_endpoints ();
@@ -362,30 +579,48 @@ static void usbtty_init_strings (void)
 {
 	struct usb_string_descriptor *string;
 
+	usbtty_string_table[STR_LANG] =
+		(struct usb_string_descriptor*)wstrLang;
+
 	string = (struct usb_string_descriptor *) wstrManufacturer;
-	string->bLength = sizeof (wstrManufacturer);
+	string->bLength = sizeof(wstrManufacturer);
 	string->bDescriptorType = USB_DT_STRING;
 	str2wide (CONFIG_USBD_MANUFACTURER, string->wData);
+	usbtty_string_table[STR_MANUFACTURER]=string;
+
 
 	string = (struct usb_string_descriptor *) wstrProduct;
-	string->bLength = sizeof (wstrProduct);
+	string->bLength = sizeof(wstrProduct);
 	string->bDescriptorType = USB_DT_STRING;
 	str2wide (CONFIG_USBD_PRODUCT_NAME, string->wData);
+	usbtty_string_table[STR_PRODUCT]=string;
+
 
 	string = (struct usb_string_descriptor *) wstrSerial;
-	string->bLength = 2 + 2*strlen(serial_number);
+	string->bLength = sizeof(serial_number);
 	string->bDescriptorType = USB_DT_STRING;
 	str2wide (serial_number, string->wData);
+	usbtty_string_table[STR_SERIAL]=string;
+
 
 	string = (struct usb_string_descriptor *) wstrConfiguration;
-	string->bLength = sizeof (wstrConfiguration);
+	string->bLength = sizeof(wstrConfiguration);
 	string->bDescriptorType = USB_DT_STRING;
 	str2wide (CONFIG_USBD_CONFIGURATION_STR, string->wData);
+	usbtty_string_table[STR_CONFIG]=string;
 
-	string = (struct usb_string_descriptor *) wstrInterface;
-	string->bLength = sizeof (wstrInterface);
+
+	string = (struct usb_string_descriptor *) wstrDataInterface;
+	string->bLength = sizeof(wstrDataInterface);
 	string->bDescriptorType = USB_DT_STRING;
-	str2wide (CONFIG_USBD_INTERFACE_STR, string->wData);
+	str2wide (CONFIG_USBD_DATA_INTERFACE_STR, string->wData);
+	usbtty_string_table[STR_DATA_INTERFACE]=string;
+
+	string = (struct usb_string_descriptor *) wstrCtrlInterface;
+	string->bLength = sizeof(wstrCtrlInterface);
+	string->bDescriptorType = USB_DT_STRING;
+	str2wide (CONFIG_USBD_CTRL_INTERFACE_STR, string->wData);
+	usbtty_string_table[STR_CTRL_INTERFACE]=string;
 
 	/* Now, initialize the string table for ep0 handling */
 	usb_strings = usbtty_string_table;
@@ -400,6 +635,7 @@ static void usbtty_init_instances (void)
 	device_instance->device_state = STATE_INIT;
 	device_instance->device_descriptor = &device_descriptor;
 	device_instance->event = usbtty_event_handler;
+	device_instance->cdc_recv_setup = usbtty_cdc_setup;
 	device_instance->bus = bus_instance;
 	device_instance->configurations = NUM_CONFIGS;
 	device_instance->configuration_instance_array = config_instance;
@@ -415,8 +651,8 @@ static void usbtty_init_instances (void)
 	/* configuration instance */
 	memset (config_instance, 0,
 		sizeof (struct usb_configuration_instance));
-	config_instance->interfaces = NUM_INTERFACES;
-	config_instance->configuration_descriptor = config_descriptors;
+	config_instance->interfaces = interface_count;
+	config_instance->configuration_descriptor = configuration_descriptor;
 	config_instance->interface_instance_array = interface_instance;
 
 	/* interface instance */
@@ -447,17 +683,22 @@ static void usbtty_init_instances (void)
 			sizeof (struct usb_endpoint_instance));
 
 		endpoint_instance[i].endpoint_address =
-			ep_descriptors[i - 1].bEndpointAddress;
+			ep_descriptor_ptrs[i - 1]->bEndpointAddress;
 
-		endpoint_instance[i].rcv_packetSize =
-			ep_descriptors[i - 1].wMaxPacketSize;
 		endpoint_instance[i].rcv_attributes =
-			ep_descriptors[i - 1].bmAttributes;
+			ep_descriptor_ptrs[i - 1]->bmAttributes;
+
+		endpoint_instance[i].rcv_packetSize =
+			le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
+
+		endpoint_instance[i].tx_attributes =
+			ep_descriptor_ptrs[i - 1]->bmAttributes;
 
 		endpoint_instance[i].tx_packetSize =
-			ep_descriptors[i - 1].wMaxPacketSize;
+			le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
+
 		endpoint_instance[i].tx_attributes =
-			ep_descriptors[i - 1].bmAttributes;
+			ep_descriptor_ptrs[i - 1]->bmAttributes;
 
 		urb_link_init (&endpoint_instance[i].rcv);
 		urb_link_init (&endpoint_instance[i].rdy);
@@ -480,13 +721,79 @@ static void usbtty_init_endpoints (void)
 	int i;
 
 	bus_instance->max_endpoints = NUM_ENDPOINTS + 1;
-	for (i = 0; i <= NUM_ENDPOINTS; i++) {
+	for (i = 1; i <= NUM_ENDPOINTS; i++) {
 		udc_setup_ep (device_instance, i, &endpoint_instance[i]);
 	}
 }
 
+/* usbtty_init_terminal_type
+ *
+ * Do some late binding for our device type.
+ */
+static void usbtty_init_terminal_type(short type)
+{
+	switch(type){
+		/* CDC ACM */
+		case 0:
+			/* Assign endpoint descriptors */
+			ep_descriptor_ptrs[0] =
+				&acm_configuration_descriptors[0].notification_endpoint;
+			ep_descriptor_ptrs[1] =
+				&acm_configuration_descriptors[0].data_endpoints[0];
+			ep_descriptor_ptrs[2] =
+				&acm_configuration_descriptors[0].data_endpoints[1];
+
+			/* Enumerate Device Descriptor */
+			device_descriptor.bDeviceClass =
+				COMMUNICATIONS_DEVICE_CLASS;
+			device_descriptor.idProduct =
+				cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM);
+
+			/* Assign endpoint indices */
+			tx_endpoint = ACM_TX_ENDPOINT;
+			rx_endpoint = ACM_RX_ENDPOINT;
+
+			/* Configuration Descriptor */
+			configuration_descriptor =
+				(struct usb_configuration_descriptor*)
+				&acm_configuration_descriptors;
+
+			/* Interface count */
+			interface_count = NUM_ACM_INTERFACES;
+		break;
+
+		/* BULK IN/OUT & Default */
+		case 1:
+		default:
+			/* Assign endpoint descriptors */
+			ep_descriptor_ptrs[0] =
+				&gserial_configuration_descriptors[0].data_endpoints[0];
+			ep_descriptor_ptrs[1] =
+				&gserial_configuration_descriptors[0].data_endpoints[1];
+			ep_descriptor_ptrs[2] =
+				&gserial_configuration_descriptors[0].data_endpoints[2];
+
+			/* Enumerate Device Descriptor */
+			device_descriptor.bDeviceClass = 0xFF;
+			device_descriptor.idProduct =
+				cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL);
+
+			/* Assign endpoint indices */
+			tx_endpoint = GSERIAL_TX_ENDPOINT;
+			rx_endpoint = GSERIAL_RX_ENDPOINT;
+
+			/* Configuration Descriptor */
+			configuration_descriptor =
+				(struct usb_configuration_descriptor*)
+				&gserial_configuration_descriptors;
+
+			/* Interface count */
+			interface_count = NUM_GSERIAL_INTERFACES;
+		break;
+	}
+}
 
-/*********************************************************************************/
+/******************************************************************************/
 
 static struct urb *next_urb (struct usb_device_instance *device,
 			     struct usb_endpoint_instance *endpoint)
@@ -526,27 +833,39 @@ static int write_buffer (circbuf_t * buf)
 		return 0;
 	}
 
-	if (buf->size) {
+	struct usb_endpoint_instance *endpoint =
+			&endpoint_instance[tx_endpoint];
+	struct urb *current_urb = NULL;
 
-		struct usb_endpoint_instance *endpoint =
-			&endpoint_instance[TX_ENDPOINT];
-		struct urb *current_urb = NULL;
+	current_urb = next_urb (device_instance, endpoint);
+	/* TX data still exists - send it now
+	 */
+	if(endpoint->sent < current_urb->actual_length){
+		if(udc_endpoint_write (endpoint)){
+			/* Write pre-empted by RX */
+			return -1;
+		}
+	}
+
+	if (buf->size) {
 		char *dest;
 
 		int space_avail;
 		int popnum, popped;
 		int total = 0;
 
-		/* Break buffer into urb sized pieces, and link each to the endpoint */
+		/* Break buffer into urb sized pieces,
+		 * and link each to the endpoint
+		 */
 		while (buf->size > 0) {
-			current_urb = next_urb (device_instance, endpoint);
+
 			if (!current_urb) {
 				TTYERR ("current_urb is NULL, buf->size %d\n",
 					buf->size);
 				return total;
 			}
 
-			dest = current_urb->buffer +
+			dest = (char*)current_urb->buffer +
 				current_urb->actual_length;
 
 			space_avail =
@@ -562,14 +881,19 @@ static int write_buffer (circbuf_t * buf)
 			current_urb->actual_length += popped;
 			total += popped;
 
-			/* If endpoint->last == 0, then transfers have not started on this endpoint */
+			/* If endpoint->last == 0, then transfers have
+			 * not started on this endpoint
+			 */
 			if (endpoint->last == 0) {
-				udc_endpoint_write (endpoint);
+				if(udc_endpoint_write (endpoint)){
+					/* Write pre-empted by RX */
+					return -1;
+				}
 			}
 
-		}		/* end while */
+		}/* end while */
 		return total;
-	}			/* end if tx_urb */
+	}
 
 	return 0;
 }
@@ -577,18 +901,22 @@ static int write_buffer (circbuf_t * buf)
 static int fill_buffer (circbuf_t * buf)
 {
 	struct usb_endpoint_instance *endpoint =
-		&endpoint_instance[RECV_ENDPOINT];
+		&endpoint_instance[rx_endpoint];
 
 	if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) {
-		unsigned int nb = endpoint->rcv_urb->actual_length;
+		unsigned int nb = 0;
 		char *src = (char *) endpoint->rcv_urb->buffer;
+		unsigned int rx_avail = buf->totalsize - buf->size;
+
+		if(rx_avail >= endpoint->rcv_urb->actual_length){
 
-		buf_push (buf, src, nb);
-		endpoint->rcv_urb->actual_length = 0;
+			nb = endpoint->rcv_urb->actual_length;
+			buf_push (buf, src, nb);
+			endpoint->rcv_urb->actual_length = 0;
 
+		}
 		return nb;
 	}
-
 	return 0;
 }
 
@@ -597,7 +925,7 @@ static int usbtty_configured (void)
 	return usbtty_configured_flag;
 }
 
-/*********************************************************************************/
+/******************************************************************************/
 
 static void usbtty_event_handler (struct usb_device_instance *device,
 				  usb_device_event_t event, int data)
@@ -619,8 +947,34 @@ static void usbtty_event_handler (struct usb_device_instance *device,
 	}
 }
 
-/*********************************************************************************/
+/******************************************************************************/
+
+int usbtty_cdc_setup(struct usb_device_request *request, struct urb *urb)
+{
+	switch (request->bRequest){
+
+	   	case ACM_SET_CONTROL_LINE_STATE:	/* Implies DTE ready */
+			break;
+	   	case ACM_SEND_ENCAPSULATED_COMMAND :	/* Required */
+			break;
+		case ACM_SET_LINE_ENCODING :		/* DTE stop/parity bits
+							 * per character */
+			break;
+	   	case ACM_GET_ENCAPSULATED_RESPONSE :	/* request response */
+			break;
+		case ACM_GET_LINE_ENCODING :		/* request DTE rate,
+							 * stop/parity bits */
+			memcpy (urb->buffer , &rs232_desc, sizeof(rs232_desc));
+			urb->actual_length = sizeof(rs232_desc);
+
+			break;
+	 	default:
+			return 1;
+	}
+	return 0;
+}
 
+/******************************************************************************/
 
 /*
  * Since interrupt handling has not yet been implemented, we use this function
@@ -630,36 +984,29 @@ static void usbtty_event_handler (struct usb_device_instance *device,
 void usbtty_poll (void)
 {
 	/* New interrupts? */
-	pretend_interrupts ();
+	udc_irq();
 
-	/* Write any output data to host buffer (do this before checking interrupts to avoid missing one) */
+	/* Write any output data to host buffer
+	 * (do this before checking interrupts to avoid missing one)
+	 */
 	if (usbtty_configured ()) {
 		write_buffer (&usbtty_output);
 	}
 
 	/* New interrupts? */
-	pretend_interrupts ();
+	udc_irq();
 
-	/* Check for new data from host.. (do this after checking interrupts to get latest data) */
+	/* Check for new data from host..
+	 * (do this after checking interrupts to get latest data)
+	 */
 	if (usbtty_configured ()) {
 		fill_buffer (&usbtty_input);
 	}
 
 	/* New interrupts? */
-	pretend_interrupts ();
-}
+	udc_irq();
 
-static void pretend_interrupts (void)
-{
-	/* Loop while we have interrupts.
-	 * If we don't do this, the input chain
-	 * polling delay is likely to miss
-	 * host requests.
-	 */
-	while (inw (UDC_IRQ_SRC) & ~UDC_SOF_Flg) {
-		/* Handle any new IRQs */
-		omap1510_udc_irq ();
-		omap1510_udc_noniso_irq ();
-	}
 }
+
+
 #endif
diff --git a/drivers/usbtty.h b/drivers/usbtty.h
index 79c2fe57d7adf4e22a1230bd4218c04623b363e2..8154e3072ef4b0c789fd91b01a116c1c230412a4 100644
--- a/drivers/usbtty.h
+++ b/drivers/usbtty.h
@@ -2,6 +2,9 @@
  * (C) Copyright 2003
  * Gerry Hamel, geh@ti.com, Texas Instruments
  *
+ * (C) Copyright 2006
+ * Bryan O'Donoghue, bodonoghue@codehermit.ie, CodeHermit
+ *
  * 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
@@ -21,44 +24,47 @@
 #ifndef __USB_TTY_H__
 #define __USB_TTY_H__
 
-
 #include "usbdcore.h"
+#if defined(CONFIG_PPC)
+#include "usbdcore_mpc8xx.h"
+#elif defined(CONFIG_ARM)
 #include "usbdcore_omap1510.h"
+#endif
 
+#include <version_autogenerated.h>
 
-#define NUM_CONFIGS    1
-#define NUM_INTERFACES 1
-#define NUM_ENDPOINTS  3
+/* If no VendorID/ProductID is defined in config.h, pretend to be Linux
+ * DO NOT Reuse this Vendor/Product setup with protocol incompatible devices */
 
-#define EP0_MAX_PACKET_SIZE 64
+#define CONFIG_USBD_VENDORID 0x0525 	/* Linux/NetChip */
+#define CONFIG_USBD_PRODUCTID_GSERIAL 0xa4a6	/* gserial */
+#define CONFIG_USBD_PRODUCTID_CDCACM  0xa4a7	/* CDC ACM */
+#define CONFIG_USBD_MANUFACTURER "Das U-Boot"
+#define CONFIG_USBD_PRODUCT_NAME U_BOOT_VERSION
 
-#define CONFIG_USBD_CONFIGURATION_STR "TTY via USB"
-#define CONFIG_USBD_INTERFACE_STR     "Simple Serial Data Interface - Bulk Mode"
 
+#define CONFIG_USBD_CONFIGURATION_STR "TTY via USB"
 
-#define CONFIG_USBD_SERIAL_OUT_ENDPOINT 2
-#define CONFIG_USBD_SERIAL_OUT_PKTSIZE	64
-#define CONFIG_USBD_SERIAL_IN_ENDPOINT	1
-#define CONFIG_USBD_SERIAL_IN_PKTSIZE	64
-#define CONFIG_USBD_SERIAL_INT_ENDPOINT 5
-#define CONFIG_USBD_SERIAL_INT_PKTSIZE	16
-
+#define CONFIG_USBD_SERIAL_OUT_ENDPOINT UDC_OUT_ENDPOINT
+#define CONFIG_USBD_SERIAL_OUT_PKTSIZE	UDC_OUT_PACKET_SIZE
+#define CONFIG_USBD_SERIAL_IN_ENDPOINT	UDC_IN_ENDPOINT
+#define CONFIG_USBD_SERIAL_IN_PKTSIZE	UDC_IN_PACKET_SIZE
+#define CONFIG_USBD_SERIAL_INT_ENDPOINT UDC_INT_ENDPOINT
+#define CONFIG_USBD_SERIAL_INT_PKTSIZE	UDC_INT_PACKET_SIZE
+#define CONFIG_USBD_SERIAL_BULK_PKTSIZE	UDC_BULK_PACKET_SIZE
 
 #define USBTTY_DEVICE_CLASS	COMMUNICATIONS_DEVICE_CLASS
-#define USBTTY_DEVICE_SUBCLASS	COMMUNICATIONS_NO_SUBCLASS
-#define USBTTY_DEVICE_PROTOCOL	COMMUNICATIONS_NO_PROTOCOL
-
-#define USBTTY_INTERFACE_CLASS	   0xFF /* Vendor Specific */
-#define USBTTY_INTERFACE_SUBCLASS  0x02
-#define USBTTY_INTERFACE_PROTOCOL  0x01
 
-#define USBTTY_BCD_DEVICE 0x0
-#define USBTTY_MAXPOWER	  0x0
+#define USBTTY_BCD_DEVICE 	0x00
+#define USBTTY_MAXPOWER	  	0x00
 
-#define STR_MANUFACTURER 1
-#define STR_PRODUCT	 2
-#define STR_SERIAL	 3
-#define STR_CONFIG	 4
-#define STR_INTERFACE	 5
+#define STR_LANG		0x00
+#define STR_MANUFACTURER	0x01
+#define STR_PRODUCT		0x02
+#define STR_SERIAL		0x03
+#define STR_CONFIG		0x04
+#define STR_DATA_INTERFACE	0x05
+#define STR_CTRL_INTERFACE	0x06
+#define STR_COUNT		0x07
 
 #endif
diff --git a/include/_exports.h b/include/_exports.h
index da6e088163e48d55edd45fbd8b50407864cffc26..af43885c5278c7659bcb04275d5b775f196f4b0e 100644
--- a/include/_exports.h
+++ b/include/_exports.h
@@ -14,6 +14,9 @@ EXPORT_FUNC(vprintf)
 EXPORT_FUNC(do_reset)
 EXPORT_FUNC(getenv)
 EXPORT_FUNC(setenv)
+#ifdef CONFIG_HAS_UID
+EXPORT_FUNC(forceenv)
+#endif
 EXPORT_FUNC(simple_strtoul)
 EXPORT_FUNC(simple_strtol)
 EXPORT_FUNC(strcmp)
diff --git a/include/asm-arm/arch-davinci/emac_defs.h b/include/asm-arm/arch-davinci/emac_defs.h
new file mode 100644
index 0000000000000000000000000000000000000000..0e10116d87051e6da3138603e290836f10f5b4f1
--- /dev/null
+++ b/include/asm-arm/arch-davinci/emac_defs.h
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Based on:
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * dm644x_emac.h
+ *
+ * TI DaVinci (DM644X) EMAC peripheral driver header for DV-EVM
+ *
+ * Copyright (C) 2005 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+
+ * Modifications:
+ * ver. 1.0: Sep 2005, TI PSP Team - Created EMAC version for uBoot.
+ *
+ */
+
+#ifndef _DM644X_EMAC_H_
+#define _DM644X_EMAC_H_
+
+#include <asm/arch/hardware.h>
+
+#define EMAC_BASE_ADDR			(0x01c80000)
+#define EMAC_WRAPPER_BASE_ADDR		(0x01c81000)
+#define EMAC_WRAPPER_RAM_ADDR		(0x01c82000)
+#define EMAC_MDIO_BASE_ADDR		(0x01c84000)
+
+/* MDIO module input frequency */
+#define EMAC_MDIO_BUS_FREQ		99000000	/* PLL/6 - 99 MHz */
+/* MDIO clock output frequency */
+#define EMAC_MDIO_CLOCK_FREQ		2000000		/* 2.0 MHz */
+
+/* Ethernet Min/Max packet size */
+#define EMAC_MIN_ETHERNET_PKT_SIZE	60
+#define EMAC_MAX_ETHERNET_PKT_SIZE	1518
+#define EMAC_PKT_ALIGN			18	/* 1518 + 18 = 1536 (packet aligned on 32 byte boundry) */
+
+/* Number of RX packet buffers
+ * NOTE: Only 1 buffer supported as of now
+ */
+#define EMAC_MAX_RX_BUFFERS		10
+
+
+/***********************************************
+ ******** Internally used macros ***************
+ ***********************************************/
+
+#define EMAC_CH_TX			1
+#define EMAC_CH_RX			0
+
+/* Each descriptor occupies 4 words, lets start RX desc's at 0 and
+ * reserve space for 64 descriptors max
+ */
+#define EMAC_RX_DESC_BASE		0x0
+#define EMAC_TX_DESC_BASE		0x1000
+
+/* EMAC Teardown value */
+#define EMAC_TEARDOWN_VALUE		0xfffffffc
+
+/* MII Status Register */
+#define MII_STATUS_REG			1
+
+/* Number of statistics registers */
+#define EMAC_NUM_STATS			36
+
+
+/* EMAC Descriptor */
+typedef volatile struct _emac_desc
+{
+	u_int32_t	next;		/* Pointer to next descriptor in chain */
+	u_int8_t	*buffer;	/* Pointer to data buffer */
+	u_int32_t	buff_off_len;	/* Buffer Offset(MSW) and Length(LSW) */
+	u_int32_t	pkt_flag_len;	/* Packet Flags(MSW) and Length(LSW) */
+} emac_desc;
+
+/* CPPI bit positions */
+#define EMAC_CPPI_SOP_BIT		(0x80000000)
+#define EMAC_CPPI_EOP_BIT		(0x40000000)
+#define EMAC_CPPI_OWNERSHIP_BIT		(0x20000000)
+#define EMAC_CPPI_EOQ_BIT		(0x10000000)
+#define EMAC_CPPI_TEARDOWN_COMPLETE_BIT	(0x08000000)
+#define EMAC_CPPI_PASS_CRC_BIT		(0x04000000)
+
+#define EMAC_CPPI_RX_ERROR_FRAME	(0x03fc0000)
+
+#define EMAC_MACCONTROL_MIIEN_ENABLE		(0x20)
+#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE	(0x1)
+
+#define EMAC_RXMBPENABLE_RXCAFEN_ENABLE	(0x200000)
+#define EMAC_RXMBPENABLE_RXBROADEN	(0x2000)
+
+
+#define MDIO_CONTROL_IDLE		(0x80000000)
+#define MDIO_CONTROL_ENABLE		(0x40000000)
+#define MDIO_CONTROL_FAULT_ENABLE	(0x40000)
+#define MDIO_CONTROL_FAULT		(0x80000)
+#define MDIO_USERACCESS0_GO		(0x80000000)
+#define MDIO_USERACCESS0_WRITE_READ	(0x0)
+#define MDIO_USERACCESS0_WRITE_WRITE	(0x40000000)
+#define MDIO_USERACCESS0_ACK		(0x20000000)
+
+/* Ethernet MAC Registers Structure */
+typedef struct  {
+	dv_reg		TXIDVER;
+	dv_reg		TXCONTROL;
+	dv_reg		TXTEARDOWN;
+	u_int8_t	RSVD0[4];
+	dv_reg		RXIDVER;
+	dv_reg		RXCONTROL;
+	dv_reg		RXTEARDOWN;
+	u_int8_t	RSVD1[100];
+	dv_reg		TXINTSTATRAW;
+	dv_reg		TXINTSTATMASKED;
+	dv_reg		TXINTMASKSET;
+	dv_reg		TXINTMASKCLEAR;
+	dv_reg		MACINVECTOR;
+	u_int8_t	RSVD2[12];
+	dv_reg		RXINTSTATRAW;
+	dv_reg		RXINTSTATMASKED;
+	dv_reg		RXINTMASKSET;
+	dv_reg		RXINTMASKCLEAR;
+	dv_reg		MACINTSTATRAW;
+	dv_reg		MACINTSTATMASKED;
+	dv_reg		MACINTMASKSET;
+	dv_reg		MACINTMASKCLEAR;
+	u_int8_t	RSVD3[64];
+	dv_reg		RXMBPENABLE;
+	dv_reg		RXUNICASTSET;
+	dv_reg		RXUNICASTCLEAR;
+	dv_reg		RXMAXLEN;
+	dv_reg		RXBUFFEROFFSET;
+	dv_reg		RXFILTERLOWTHRESH;
+	u_int8_t	RSVD4[8];
+	dv_reg		RX0FLOWTHRESH;
+	dv_reg		RX1FLOWTHRESH;
+	dv_reg		RX2FLOWTHRESH;
+	dv_reg		RX3FLOWTHRESH;
+	dv_reg		RX4FLOWTHRESH;
+	dv_reg		RX5FLOWTHRESH;
+	dv_reg		RX6FLOWTHRESH;
+	dv_reg		RX7FLOWTHRESH;
+	dv_reg		RX0FREEBUFFER;
+	dv_reg		RX1FREEBUFFER;
+	dv_reg		RX2FREEBUFFER;
+	dv_reg		RX3FREEBUFFER;
+	dv_reg		RX4FREEBUFFER;
+	dv_reg		RX5FREEBUFFER;
+	dv_reg		RX6FREEBUFFER;
+	dv_reg		RX7FREEBUFFER;
+	dv_reg		MACCONTROL;
+	dv_reg		MACSTATUS;
+	dv_reg		EMCONTROL;
+	dv_reg		FIFOCONTROL;
+	dv_reg		MACCONFIG;
+	dv_reg		SOFTRESET;
+	u_int8_t	RSVD5[88];
+	dv_reg		MACSRCADDRLO;
+	dv_reg		MACSRCADDRHI;
+	dv_reg		MACHASH1;
+	dv_reg		MACHASH2;
+	dv_reg		BOFFTEST;
+	dv_reg		TPACETEST;
+	dv_reg		RXPAUSE;
+	dv_reg		TXPAUSE;
+	u_int8_t	RSVD6[16];
+	dv_reg		RXGOODFRAMES;
+	dv_reg		RXBCASTFRAMES;
+	dv_reg		RXMCASTFRAMES;
+	dv_reg		RXPAUSEFRAMES;
+	dv_reg		RXCRCERRORS;
+	dv_reg		RXALIGNCODEERRORS;
+	dv_reg		RXOVERSIZED;
+	dv_reg		RXJABBER;
+	dv_reg		RXUNDERSIZED;
+	dv_reg		RXFRAGMENTS;
+	dv_reg		RXFILTERED;
+	dv_reg		RXQOSFILTERED;
+	dv_reg		RXOCTETS;
+	dv_reg		TXGOODFRAMES;
+	dv_reg		TXBCASTFRAMES;
+	dv_reg		TXMCASTFRAMES;
+	dv_reg		TXPAUSEFRAMES;
+	dv_reg		TXDEFERRED;
+	dv_reg		TXCOLLISION;
+	dv_reg		TXSINGLECOLL;
+	dv_reg		TXMULTICOLL;
+	dv_reg		TXEXCESSIVECOLL;
+	dv_reg		TXLATECOLL;
+	dv_reg		TXUNDERRUN;
+	dv_reg		TXCARRIERSENSE;
+	dv_reg		TXOCTETS;
+	dv_reg		FRAME64;
+	dv_reg		FRAME65T127;
+	dv_reg		FRAME128T255;
+	dv_reg		FRAME256T511;
+	dv_reg		FRAME512T1023;
+	dv_reg		FRAME1024TUP;
+	dv_reg		NETOCTETS;
+	dv_reg		RXSOFOVERRUNS;
+	dv_reg		RXMOFOVERRUNS;
+	dv_reg		RXDMAOVERRUNS;
+	u_int8_t	RSVD7[624];
+	dv_reg		MACADDRLO;
+	dv_reg		MACADDRHI;
+	dv_reg		MACINDEX;
+	u_int8_t	RSVD8[244];
+	dv_reg		TX0HDP;
+	dv_reg		TX1HDP;
+	dv_reg		TX2HDP;
+	dv_reg		TX3HDP;
+	dv_reg		TX4HDP;
+	dv_reg		TX5HDP;
+	dv_reg		TX6HDP;
+	dv_reg		TX7HDP;
+	dv_reg		RX0HDP;
+	dv_reg		RX1HDP;
+	dv_reg		RX2HDP;
+	dv_reg		RX3HDP;
+	dv_reg		RX4HDP;
+	dv_reg		RX5HDP;
+	dv_reg		RX6HDP;
+	dv_reg		RX7HDP;
+	dv_reg		TX0CP;
+	dv_reg		TX1CP;
+	dv_reg		TX2CP;
+	dv_reg		TX3CP;
+	dv_reg		TX4CP;
+	dv_reg		TX5CP;
+	dv_reg		TX6CP;
+	dv_reg		TX7CP;
+	dv_reg		RX0CP;
+	dv_reg		RX1CP;
+	dv_reg		RX2CP;
+	dv_reg		RX3CP;
+	dv_reg		RX4CP;
+	dv_reg		RX5CP;
+	dv_reg		RX6CP;
+	dv_reg		RX7CP;
+} emac_regs;
+
+/* EMAC Wrapper Registers Structure */
+typedef struct  {
+	u_int8_t	RSVD0[4100];
+	dv_reg		EWCTL;
+	dv_reg		EWINTTCNT;
+} ewrap_regs;
+
+
+/* EMAC MDIO Registers Structure */
+typedef struct  {
+	dv_reg		VERSION;
+	dv_reg		CONTROL;
+	dv_reg		ALIVE;
+	dv_reg		LINK;
+	dv_reg		LINKINTRAW;
+	dv_reg		LINKINTMASKED;
+	u_int8_t	RSVD0[8];
+	dv_reg		USERINTRAW;
+	dv_reg		USERINTMASKED;
+	dv_reg		USERINTMASKSET;
+	dv_reg		USERINTMASKCLEAR;
+	u_int8_t	RSVD1[80];
+	dv_reg		USERACCESS0;
+	dv_reg		USERPHYSEL0;
+	dv_reg		USERACCESS1;
+	dv_reg		USERPHYSEL1;
+} mdio_regs;
+
+int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data);
+int dm644x_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data);
+
+typedef struct
+{
+	char	name[64];
+	int	(*init)(int phy_addr);
+	int	(*is_phy_connected)(int phy_addr);
+	int	(*get_link_speed)(int phy_addr);
+	int	(*auto_negotiate)(int phy_addr);
+} phy_t;
+
+#define PHY_LXT972	(0x001378e2)
+int lxt972_is_phy_connected(int phy_addr);
+int lxt972_get_link_speed(int phy_addr);
+int lxt972_init_phy(int phy_addr);
+int lxt972_auto_negotiate(int phy_addr);
+
+#define PHY_DP83848	(0x20005c90)
+int dp83848_is_phy_connected(int phy_addr);
+int dp83848_get_link_speed(int phy_addr);
+int dp83848_init_phy(int phy_addr);
+int dp83848_auto_negotiate(int phy_addr);
+
+#endif  /* _DM644X_EMAC_H_ */
diff --git a/include/asm-arm/arch-davinci/emif_defs.h b/include/asm-arm/arch-davinci/emif_defs.h
new file mode 100644
index 0000000000000000000000000000000000000000..646fc7746940dac5c25c3db4c3ba4b83df8f087c
--- /dev/null
+++ b/include/asm-arm/arch-davinci/emif_defs.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef _EMIF_DEFS_H_
+#define _EMIF_DEFS_H_
+
+#include <asm/arch/hardware.h>
+
+typedef struct {
+	dv_reg		ERCSR;
+	dv_reg		AWCCR;
+	dv_reg		SDBCR;
+	dv_reg		SDRCR;
+	dv_reg		AB1CR;
+	dv_reg		AB2CR;
+	dv_reg		AB3CR;
+	dv_reg		AB4CR;
+	dv_reg		SDTIMR;
+	dv_reg		DDRSR;
+	dv_reg		DDRPHYCR;
+	dv_reg		DDRPHYSR;
+	dv_reg		TOTAR;
+	dv_reg		TOTACTR;
+	dv_reg		DDRPHYID_REV;
+	dv_reg		SDSRETR;
+	dv_reg		EIRR;
+	dv_reg		EIMR;
+	dv_reg		EIMSR;
+	dv_reg		EIMCR;
+	dv_reg		IOCTRLR;
+	dv_reg		IOSTATR;
+	u_int8_t	RSVD0[8];
+	dv_reg		NANDFCR;
+	dv_reg		NANDFSR;
+	u_int8_t	RSVD1[8];
+	dv_reg		NANDF1ECC;
+	dv_reg		NANDF2ECC;
+	dv_reg		NANDF3ECC;
+	dv_reg		NANDF4ECC;
+} emif_registers;
+
+typedef emif_registers	*emifregs;
+#endif
diff --git a/include/asm-arm/arch-davinci/hardware.h b/include/asm-arm/arch-davinci/hardware.h
new file mode 100644
index 0000000000000000000000000000000000000000..ebcdcfea1e9960d9f44c323cd87baf547b375e75
--- /dev/null
+++ b/include/asm-arm/arch-davinci/hardware.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Based on:
+ *
+ * -------------------------------------------------------------------------
+ *
+ *  linux/include/asm-arm/arch-davinci/hardware.h
+ *
+ *  Copyright (C) 2006 Texas Instruments.
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <config.h>
+#include <asm/sizes.h>
+
+#define	REG(addr)	(*(volatile unsigned int *)(addr))
+#define REG_P(addr)	((volatile unsigned int *)(addr))
+
+typedef volatile unsigned int	dv_reg;
+typedef volatile unsigned int *	dv_reg_p;
+
+/*
+ * Base register addresses
+ */
+#define DAVINCI_DMA_3PCC_BASE			(0x01c00000)
+#define DAVINCI_DMA_3PTC0_BASE			(0x01c10000)
+#define DAVINCI_DMA_3PTC1_BASE			(0x01c10400)
+#define DAVINCI_UART0_BASE			(0x01c20000)
+#define DAVINCI_UART1_BASE			(0x01c20400)
+#define DAVINCI_UART2_BASE			(0x01c20800)
+#define DAVINCI_I2C_BASE			(0x01c21000)
+#define DAVINCI_TIMER0_BASE			(0x01c21400)
+#define DAVINCI_TIMER1_BASE			(0x01c21800)
+#define DAVINCI_WDOG_BASE			(0x01c21c00)
+#define DAVINCI_PWM0_BASE			(0x01c22000)
+#define DAVINCI_PWM1_BASE			(0x01c22400)
+#define DAVINCI_PWM2_BASE			(0x01c22800)
+#define DAVINCI_SYSTEM_MODULE_BASE		(0x01c40000)
+#define DAVINCI_PLL_CNTRL0_BASE			(0x01c40800)
+#define DAVINCI_PLL_CNTRL1_BASE			(0x01c40c00)
+#define DAVINCI_PWR_SLEEP_CNTRL_BASE		(0x01c41000)
+#define DAVINCI_SYSTEM_DFT_BASE			(0x01c42000)
+#define DAVINCI_ARM_INTC_BASE			(0x01c48000)
+#define DAVINCI_IEEE1394_BASE			(0x01c60000)
+#define DAVINCI_USB_OTG_BASE			(0x01c64000)
+#define DAVINCI_CFC_ATA_BASE			(0x01c66000)
+#define DAVINCI_SPI_BASE			(0x01c66800)
+#define DAVINCI_GPIO_BASE			(0x01c67000)
+#define DAVINCI_UHPI_BASE			(0x01c67800)
+#define DAVINCI_VPSS_REGS_BASE			(0x01c70000)
+#define DAVINCI_EMAC_CNTRL_REGS_BASE		(0x01c80000)
+#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE	(0x01c81000)
+#define DAVINCI_EMAC_WRAPPER_RAM_BASE		(0x01c82000)
+#define DAVINCI_MDIO_CNTRL_REGS_BASE		(0x01c84000)
+#define DAVINCI_IMCOP_BASE			(0x01cc0000)
+#define DAVINCI_ASYNC_EMIF_CNTRL_BASE		(0x01e00000)
+#define DAVINCI_VLYNQ_BASE			(0x01e01000)
+#define DAVINCI_MCBSP_BASE			(0x01e02000)
+#define DAVINCI_MMC_SD_BASE			(0x01e10000)
+#define DAVINCI_MS_BASE				(0x01e20000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	(0x02000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE	(0x04000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE	(0x06000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE	(0x08000000)
+#define DAVINCI_VLYNQ_REMOTE_BASE		(0x0c000000)
+
+/* Power and Sleep Controller (PSC) Domains */
+#define DAVINCI_GPSC_ARMDOMAIN		0
+#define DAVINCI_GPSC_DSPDOMAIN		1
+
+#define DAVINCI_LPSC_VPSSMSTR		0
+#define DAVINCI_LPSC_VPSSSLV		1
+#define DAVINCI_LPSC_TPCC		2
+#define DAVINCI_LPSC_TPTC0		3
+#define DAVINCI_LPSC_TPTC1		4
+#define DAVINCI_LPSC_EMAC		5
+#define DAVINCI_LPSC_EMAC_WRAPPER	6
+#define DAVINCI_LPSC_MDIO		7
+#define DAVINCI_LPSC_IEEE1394		8
+#define DAVINCI_LPSC_USB		9
+#define DAVINCI_LPSC_ATA		10
+#define DAVINCI_LPSC_VLYNQ		11
+#define DAVINCI_LPSC_UHPI		12
+#define DAVINCI_LPSC_DDR_EMIF		13
+#define DAVINCI_LPSC_AEMIF		14
+#define DAVINCI_LPSC_MMC_SD		15
+#define DAVINCI_LPSC_MEMSTICK		16
+#define DAVINCI_LPSC_McBSP		17
+#define DAVINCI_LPSC_I2C		18
+#define DAVINCI_LPSC_UART0		19
+#define DAVINCI_LPSC_UART1		20
+#define DAVINCI_LPSC_UART2		21
+#define DAVINCI_LPSC_SPI		22
+#define DAVINCI_LPSC_PWM0		23
+#define DAVINCI_LPSC_PWM1		24
+#define DAVINCI_LPSC_PWM2		25
+#define DAVINCI_LPSC_GPIO		26
+#define DAVINCI_LPSC_TIMER0		27
+#define DAVINCI_LPSC_TIMER1		28
+#define DAVINCI_LPSC_TIMER2		29
+#define DAVINCI_LPSC_SYSTEM_SUBSYS	30
+#define DAVINCI_LPSC_ARM		31
+#define DAVINCI_LPSC_SCR2		32
+#define DAVINCI_LPSC_SCR3		33
+#define DAVINCI_LPSC_SCR4		34
+#define DAVINCI_LPSC_CROSSBAR		35
+#define DAVINCI_LPSC_CFG27		36
+#define DAVINCI_LPSC_CFG3		37
+#define DAVINCI_LPSC_CFG5		38
+#define DAVINCI_LPSC_GEM		39
+#define DAVINCI_LPSC_IMCOP		40
+
+/* Some PSC defines */
+#define PSC_CHP_SHRTSW			(0x01c40038)
+#define PSC_GBLCTL			(0x01c41010)
+#define PSC_EPCPR			(0x01c41070)
+#define PSC_EPCCR			(0x01c41078)
+#define PSC_PTCMD			(0x01c41120)
+#define PSC_PTSTAT			(0x01c41128)
+#define PSC_PDSTAT			(0x01c41200)
+#define PSC_PDSTAT1			(0x01c41204)
+#define PSC_PDCTL			(0x01c41300)
+#define PSC_PDCTL1			(0x01c41304)
+
+#define PSC_MDCTL_BASE			(0x01c41a00)
+#define PSC_MDSTAT_BASE			(0x01c41800)
+
+#define VDD3P3V_PWDN			(0x01c40048)
+#define UART0_PWREMU_MGMT		(0x01c20030)
+
+#define PSC_SILVER_BULLET		(0x01c41a20)
+
+/* Some PLL defines */
+#define PLL1_PLLM			(0x01c40910)
+#define PLL2_PLLM			(0x01c40d10)
+#define PLL2_DIV2			(0x01c40d1c)
+
+/* Miscellania... */
+#define VBPR				(0x20000020)
+#define PINMUX0				(0x01c40000)
+#define PINMUX1				(0x01c40004)
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-davinci/i2c_defs.h b/include/asm-arm/arch-davinci/i2c_defs.h
new file mode 100644
index 0000000000000000000000000000000000000000..2e902e17f830be2a561f103a1ddab9bcf369763b
--- /dev/null
+++ b/include/asm-arm/arch-davinci/i2c_defs.h
@@ -0,0 +1,94 @@
+/*
+ * (C) Copyright 2004
+ * Texas Instruments, <www.ti.com>
+ *
+ * Some changes copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef _DAVINCI_I2C_H_
+#define _DAVINCI_I2C_H_
+
+#define I2C_WRITE		0
+#define I2C_READ		1
+
+#define I2C_BASE		0x01c21000
+
+#define	I2C_OA			(I2C_BASE + 0x00)
+#define I2C_IE			(I2C_BASE + 0x04)
+#define I2C_STAT		(I2C_BASE + 0x08)
+#define I2C_SCLL		(I2C_BASE + 0x0c)
+#define I2C_SCLH		(I2C_BASE + 0x10)
+#define I2C_CNT			(I2C_BASE + 0x14)
+#define I2C_DRR			(I2C_BASE + 0x18)
+#define I2C_SA			(I2C_BASE + 0x1c)
+#define I2C_DXR			(I2C_BASE + 0x20)
+#define I2C_CON			(I2C_BASE + 0x24)
+#define I2C_IV			(I2C_BASE + 0x28)
+#define I2C_PSC			(I2C_BASE + 0x30)
+
+/* I2C masks */
+
+/* I2C Interrupt Enable Register (I2C_IE): */
+#define I2C_IE_SCD_IE	(1 << 5)	/* Stop condition detect interrupt enable */
+#define I2C_IE_XRDY_IE	(1 << 4)	/* Transmit data ready interrupt enable */
+#define I2C_IE_RRDY_IE	(1 << 3)	/* Receive data ready interrupt enable */
+#define I2C_IE_ARDY_IE	(1 << 2)	/* Register access ready interrupt enable */
+#define I2C_IE_NACK_IE	(1 << 1)	/* No acknowledgment interrupt enable */
+#define I2C_IE_AL_IE	(1 << 0)	/* Arbitration lost interrupt enable */
+
+/* I2C Status Register (I2C_STAT): */
+
+#define I2C_STAT_BB	(1 << 12)	/* Bus busy */
+#define I2C_STAT_ROVR	(1 << 11)	/* Receive overrun */
+#define I2C_STAT_XUDF	(1 << 10)	/* Transmit underflow */
+#define I2C_STAT_AAS	(1 << 9)	/* Address as slave */
+#define I2C_STAT_SCD	(1 << 5)	/* Stop condition detect */
+#define I2C_STAT_XRDY	(1 << 4)	/* Transmit data ready */
+#define I2C_STAT_RRDY	(1 << 3)	/* Receive data ready */
+#define I2C_STAT_ARDY	(1 << 2)	/* Register access ready */
+#define I2C_STAT_NACK	(1 << 1)	/* No acknowledgment interrupt enable */
+#define I2C_STAT_AL	(1 << 0)	/* Arbitration lost interrupt enable */
+
+
+/* I2C Interrupt Code Register (I2C_INTCODE): */
+
+#define I2C_INTCODE_MASK	7
+#define I2C_INTCODE_NONE	0
+#define I2C_INTCODE_AL		1	/* Arbitration lost */
+#define I2C_INTCODE_NAK		2	/* No acknowledgement/general call */
+#define I2C_INTCODE_ARDY	3	/* Register access ready */
+#define I2C_INTCODE_RRDY	4	/* Rcv data ready */
+#define I2C_INTCODE_XRDY	5	/* Xmit data ready */
+#define I2C_INTCODE_SCD		6	/* Stop condition detect */
+
+
+/* I2C Configuration Register (I2C_CON): */
+
+#define I2C_CON_EN	(1 << 5)	/* I2C module enable */
+#define I2C_CON_STB	(1 << 4)	/* Start byte mode (master mode only) */
+#define I2C_CON_MST	(1 << 10)	/* Master/slave mode */
+#define I2C_CON_TRX	(1 << 9)	/* Transmitter/receiver mode (master mode only) */
+#define I2C_CON_XA	(1 << 8)	/* Expand address */
+#define I2C_CON_STP	(1 << 11)	/* Stop condition (master mode only) */
+#define I2C_CON_STT	(1 << 13)	/* Start condition (master mode only) */
+
+#define I2C_TIMEOUT	0xffff0000	/* Timeout mask for poll_i2c_irq() */
+
+#endif
diff --git a/include/asm-arm/arch-davinci/nand_defs.h b/include/asm-arm/arch-davinci/nand_defs.h
new file mode 100644
index 0000000000000000000000000000000000000000..619bd47973655649a8a3fbb6c635a9dbe9cf191f
--- /dev/null
+++ b/include/asm-arm/arch-davinci/nand_defs.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Parts shamelesly stolen from Linux Kernel source tree.
+ *
+ * ------------------------------------------------------------
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef _NAND_DEFS_H_
+#define _NAND_DEFS_H_
+
+#include <asm/arch/hardware.h>
+
+#define	MASK_CLE	0x10
+#define	MASK_ALE	0x0a
+
+#define NAND_CE0CLE	((volatile u_int8_t *)(CFG_NAND_BASE + 0x10))
+#define NAND_CE0ALE	((volatile u_int8_t *)(CFG_NAND_BASE + 0x0a))
+#define NAND_CE0DATA	((volatile u_int8_t *)CFG_NAND_BASE)
+
+typedef struct  {
+	u_int32_t	NRCSR;
+	u_int32_t	AWCCR;
+	u_int8_t	RSVD0[8];
+	u_int32_t	AB1CR;
+	u_int32_t	AB2CR;
+	u_int32_t	AB3CR;
+	u_int32_t	AB4CR;
+	u_int8_t	RSVD1[32];
+	u_int32_t	NIRR;
+	u_int32_t	NIMR;
+	u_int32_t	NIMSR;
+	u_int32_t	NIMCR;
+	u_int8_t	RSVD2[16];
+	u_int32_t	NANDFCR;
+	u_int32_t	NANDFSR;
+	u_int8_t	RSVD3[8];
+	u_int32_t	NANDF1ECC;
+	u_int32_t	NANDF2ECC;
+	u_int32_t	NANDF3ECC;
+	u_int32_t	NANDF4ECC;
+	u_int8_t	RSVD4[4];
+	u_int32_t	IODFTECR;
+	u_int32_t	IODFTGCR;
+	u_int8_t	RSVD5[4];
+	u_int32_t	IODFTMRLR;
+	u_int32_t	IODFTMRMR;
+	u_int32_t	IODFTMRMSBR;
+	u_int8_t	RSVD6[20];
+	u_int32_t	MODRNR;
+	u_int8_t	RSVD7[76];
+	u_int32_t	CE0DATA;
+	u_int32_t	CE0ALE;
+	u_int32_t	CE0CLE;
+	u_int8_t	RSVD8[4];
+	u_int32_t	CE1DATA;
+	u_int32_t	CE1ALE;
+	u_int32_t	CE1CLE;
+	u_int8_t	RSVD9[4];
+	u_int32_t	CE2DATA;
+	u_int32_t	CE2ALE;
+	u_int32_t	CE2CLE;
+	u_int8_t	RSVD10[4];
+	u_int32_t	CE3DATA;
+	u_int32_t	CE3ALE;
+	u_int32_t	CE3CLE;
+} nand_registers;
+
+typedef volatile nand_registers	*nandregs;
+
+#define NAND_READ_START		0x00
+#define NAND_READ_END		0x30
+#define NAND_STATUS		0x70
+
+#ifdef CFG_NAND_HW_ECC
+#define NAND_Ecc_P1e		(1 << 0)
+#define NAND_Ecc_P2e		(1 << 1)
+#define NAND_Ecc_P4e		(1 << 2)
+#define NAND_Ecc_P8e		(1 << 3)
+#define NAND_Ecc_P16e		(1 << 4)
+#define NAND_Ecc_P32e		(1 << 5)
+#define NAND_Ecc_P64e		(1 << 6)
+#define NAND_Ecc_P128e		(1 << 7)
+#define NAND_Ecc_P256e		(1 << 8)
+#define NAND_Ecc_P512e		(1 << 9)
+#define NAND_Ecc_P1024e		(1 << 10)
+#define NAND_Ecc_P2048e		(1 << 11)
+
+#define NAND_Ecc_P1o		(1 << 16)
+#define NAND_Ecc_P2o		(1 << 17)
+#define NAND_Ecc_P4o		(1 << 18)
+#define NAND_Ecc_P8o		(1 << 19)
+#define NAND_Ecc_P16o		(1 << 20)
+#define NAND_Ecc_P32o		(1 << 21)
+#define NAND_Ecc_P64o		(1 << 22)
+#define NAND_Ecc_P128o		(1 << 23)
+#define NAND_Ecc_P256o		(1 << 24)
+#define NAND_Ecc_P512o		(1 << 25)
+#define NAND_Ecc_P1024o		(1 << 26)
+#define NAND_Ecc_P2048o		(1 << 27)
+
+#define TF(v)			(v ? 1 : 0)
+
+#define P2048e(a)		(TF(a & NAND_Ecc_P2048e) << 0)
+#define P2048o(a)		(TF(a & NAND_Ecc_P2048o) << 1)
+#define P1e(a)			(TF(a & NAND_Ecc_P1e) << 2)
+#define P1o(a)			(TF(a & NAND_Ecc_P1o) << 3)
+#define P2e(a)			(TF(a & NAND_Ecc_P2e) << 4)
+#define P2o(a)			(TF(a & NAND_Ecc_P2o) << 5)
+#define P4e(a)			(TF(a & NAND_Ecc_P4e) << 6)
+#define P4o(a)			(TF(a & NAND_Ecc_P4o) << 7)
+
+#define P8e(a)			(TF(a & NAND_Ecc_P8e) << 0)
+#define P8o(a)			(TF(a & NAND_Ecc_P8o) << 1)
+#define P16e(a)			(TF(a & NAND_Ecc_P16e) << 2)
+#define P16o(a)			(TF(a & NAND_Ecc_P16o) << 3)
+#define P32e(a)			(TF(a & NAND_Ecc_P32e) << 4)
+#define P32o(a)			(TF(a & NAND_Ecc_P32o) << 5)
+#define P64e(a)			(TF(a & NAND_Ecc_P64e) << 6)
+#define P64o(a)			(TF(a & NAND_Ecc_P64o) << 7)
+
+#define P128e(a)		(TF(a & NAND_Ecc_P128e) << 0)
+#define P128o(a)		(TF(a & NAND_Ecc_P128o) << 1)
+#define P256e(a)		(TF(a & NAND_Ecc_P256e) << 2)
+#define P256o(a)		(TF(a & NAND_Ecc_P256o) << 3)
+#define P512e(a)		(TF(a & NAND_Ecc_P512e) << 4)
+#define P512o(a)		(TF(a & NAND_Ecc_P512o) << 5)
+#define P1024e(a)		(TF(a & NAND_Ecc_P1024e) << 6)
+#define P1024o(a)		(TF(a & NAND_Ecc_P1024o) << 7)
+
+#define P8e_s(a)		(TF(a & NAND_Ecc_P8e) << 0)
+#define P8o_s(a)		(TF(a & NAND_Ecc_P8o) << 1)
+#define P16e_s(a)		(TF(a & NAND_Ecc_P16e) << 2)
+#define P16o_s(a)		(TF(a & NAND_Ecc_P16o) << 3)
+#define P1e_s(a)		(TF(a & NAND_Ecc_P1e) << 4)
+#define P1o_s(a)		(TF(a & NAND_Ecc_P1o) << 5)
+#define P2e_s(a)		(TF(a & NAND_Ecc_P2e) << 6)
+#define P2o_s(a)		(TF(a & NAND_Ecc_P2o) << 7)
+
+#define P4e_s(a)		(TF(a & NAND_Ecc_P4e) << 0)
+#define P4o_s(a)		(TF(a & NAND_Ecc_P4o) << 1)
+#endif
+
+#endif
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index ebda7192ed07f1f2cc31f0c1a469c48918c7bb09..e8cb29903be9ab1d7e18e834cdd18e3f3b6abf40 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -592,9 +592,11 @@ typedef void		(*ExcpHndlr) (void) ;
 #define PMC_REG_BASE	__REG(0x40500400)  /* Primary Modem Codec */
 #define SMC_REG_BASE	__REG(0x40500500)  /* Secondary Modem Codec */
 
+
 /*
  * USB Device Controller
  */
+#ifndef CONFIG_CPU_MONAHANS
 #define UDC_RES1	__REG(0x40600004)  /* UDC Undocumented - Reserved1 */
 #define UDC_RES2	__REG(0x40600008)  /* UDC Undocumented - Reserved2 */
 #define UDC_RES3	__REG(0x4060000C)  /* UDC Undocumented - Reserved3 */
@@ -749,11 +751,28 @@ typedef void		(*ExcpHndlr) (void) ;
 #define USIR1_IR13	(1 << 5)	/* Interrup request ep 13 */
 #define USIR1_IR14	(1 << 6)	/* Interrup request ep 14 */
 #define USIR1_IR15	(1 << 7)	/* Interrup request ep 15 */
+#endif /* ! CONFIG_CPU_MONAHANS */
+
+#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
+
+/*
+ * USB Client Controller (incomplete)
+ */
+#define UDCCR		__REG(0x40600000)
+#define UDCICR0		__REG(0x40600004)
+#define UDCCIR0		__REG(0x40600008)
+#define UDCISR0		__REG(0x4060000c)
+#define UDCSIR1		__REG(0x40600010)
+#define UDCFNR		__REG(0x40600014)
+#define UDCOTGICR	__REG(0x40600018)
+#define UDCOTGISR	__REG(0x4060001c)
+#define UP2OCR		__REG(0x40600020)
+#define UP3OCR		__REG(0x40600024)
 
-#if defined(CONFIG_PXA27X)
 /*
  * USB Host Controller
  */
+#define OHCI_REGS_BASE	0x4C000000	/* required for ohci driver */
 #define UHCREV		__REG(0x4C000000)
 #define UHCHCON		__REG(0x4C000004)
 #define UHCCOMS		__REG(0x4C000008)
diff --git a/include/common.h b/include/common.h
index ac29d3aac6cce3d628381f3f904e2d56b4342393..27a660a4d69d51d8e03d17b40198a31ed55712cc 100644
--- a/include/common.h
+++ b/include/common.h
@@ -241,6 +241,9 @@ int	saveenv	     (void);
 void inline setenv   (char *, char *);
 #else
 void	setenv	     (char *, char *);
+#ifdef CONFIG_HAS_UID
+void	forceenv     (char *, char *);
+#endif
 #endif /* CONFIG_PPC */
 #ifdef CONFIG_ARM
 # include <asm/mach-types.h>
@@ -526,6 +529,8 @@ void	cpu_init_f    (void);
 int	cpu_init_r    (void);
 #if defined(CONFIG_8260)
 int	prt_8260_rsr  (void);
+#elif defined(CONFIG_MPC83XX)
+int	prt_83xx_rsr  (void);
 #endif
 
 /* $(CPU)/interrupts.c */
diff --git a/include/configs/AdderUSB.h b/include/configs/AdderUSB.h
new file mode 100644
index 0000000000000000000000000000000000000000..a4f7f9a28fb706434e9f34cb0933722a0571de3c
--- /dev/null
+++ b/include/configs/AdderUSB.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2006 CodeHermit.
+ * Bryan O'Donoghue <bodonoghue@codehermit.ie>
+ *
+ * Provides support for USB console on the Analogue & Micro Adder87x
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ADDERUSB__
+#define __ADDERUSB__
+
+/* Include the board port */
+#include "Adder.h"
+
+#define CONFIG_USB_DEVICE		/* Include UDC driver */
+#define CONFIG_USB_TTY			/* Bind the TTY driver to UDC */
+#define CFG_USB_EXTC_CLK 0x02		/* Oscillator on EXTC_CLK 2 */
+#define CFG_USB_BRG_CLK	0x04		/* or use Baud rate generator 0x04 */
+#define CFG_CONSOLE_IS_IN_ENV		/* Console is in env */
+
+/* If you have a USB-IF assigned VendorID then you may wish to define
+ * your own vendor specific values either in BoardName.h or directly in
+ * usbd_vendor_info.h
+ */
+
+/*
+#define CONFIG_USBD_MANUFACTURER	"CodeHermit.ie"
+#define CONFIG_USBD_PRODUCT_NAME	"Das U-Boot"
+#define CONFIG_USBD_VENDORID		0xFFFF
+#define CONFIG_USBD_PRODUCTID_GSERIAL	0xFFFF
+#define CONFIG_USBD_PRODUCTID_CDCACM	0xFFFE
+*/
+
+#endif /* __ADDERUSB_H__ */
diff --git a/include/configs/IceCube.h b/include/configs/IceCube.h
index cc902c842d563f88cbb229beed3dab9f41b936d0..1a7167b481cd0a98f824f7892ccab3206a9c7135 100644
--- a/include/configs/IceCube.h
+++ b/include/configs/IceCube.h
@@ -84,10 +84,15 @@
 #define CONFIG_ISO_PARTITION
 
 /* USB */
-#if 1
-#define CONFIG_USB_OHCI
+#define CONFIG_USB_OHCI_NEW
+#define ADD_USB_CMD             CFG_CMD_USB | CFG_CMD_FAT
 #define CONFIG_USB_STORAGE
-#endif
+#define CFG_OHCI_BE_CONTROLLER
+#undef CFG_USB_OHCI_BOARD_INIT
+#define CFG_USB_OHCI_CPU_INIT	1
+#define CFG_USB_OHCI_REGS_BASE	MPC5XXX_USB
+#define CFG_USB_OHCI_SLOT_NAME	"mpc5200"
+#define CFG_USB_OHCI_MAX_ROOT_PORTS	15
 
 #define	CONFIG_TIMESTAMP		/* Print image info with timestamp */
 
diff --git a/include/configs/MPC8323ERDB.h b/include/configs/MPC8323ERDB.h
new file mode 100644
index 0000000000000000000000000000000000000000..376973b94da0b06e4b7570c31a982e25112a1810
--- /dev/null
+++ b/include/configs/MPC8323ERDB.h
@@ -0,0 +1,583 @@
+/*
+ * Copyright (C) 2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#undef DEBUG
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_E300		1	/* E300 family */
+#define CONFIG_QE		1	/* Has QE */
+#define CONFIG_MPC83XX		1	/* MPC83xx family */
+#define CONFIG_MPC832X		1	/* MPC832x CPU specific */
+
+#define CONFIG_PCI		1
+#define CONFIG_83XX_GENERIC_PCI	1
+
+/*
+ * System Clock Setup
+ */
+#define CONFIG_83XX_CLKIN	66666667	/* in Hz */
+
+#ifndef CONFIG_SYS_CLK_FREQ
+#define CONFIG_SYS_CLK_FREQ	CONFIG_83XX_CLKIN
+#endif
+
+/*
+ * Hardware Reset Configuration Word
+ */
+#define CFG_HRCW_LOW (\
+	HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\
+	HRCWL_DDR_TO_SCB_CLK_2X1 |\
+	HRCWL_VCO_1X2 |\
+	HRCWL_CSB_TO_CLKIN_2X1 |\
+	HRCWL_CORE_TO_CSB_2_5X1 |\
+	HRCWL_CE_PLL_VCO_DIV_2 |\
+	HRCWL_CE_PLL_DIV_1X1 |\
+	HRCWL_CE_TO_PLL_1X3)
+
+#define CFG_HRCW_HIGH (\
+	HRCWH_PCI_HOST |\
+	HRCWH_PCI1_ARBITER_ENABLE |\
+	HRCWH_CORE_ENABLE |\
+	HRCWH_FROM_0X00000100 |\
+	HRCWH_BOOTSEQ_DISABLE |\
+	HRCWH_SW_WATCHDOG_DISABLE |\
+	HRCWH_ROM_LOC_LOCAL_16BIT |\
+	HRCWH_BIG_ENDIAN |\
+	HRCWH_LALE_NORMAL)
+
+/*
+ * System IO Config
+ */
+#define CFG_SICRL		0x00000000
+
+#define CONFIG_BOARD_EARLY_INIT_F	/* call board_pre_init */
+
+/*
+ * IMMR new address
+ */
+#define CFG_IMMR		0xE0000000
+
+/*
+ * DDR Setup
+ */
+#define CFG_DDR_BASE		0x00000000	/* DDR is system memory */
+#define CFG_SDRAM_BASE		CFG_DDR_BASE
+#define CFG_DDR_SDRAM_BASE	CFG_DDR_BASE
+#define CFG_DDRCDR		0x73000002	/* DDR II voltage is 1.8V */
+
+#undef CONFIG_SPD_EEPROM
+#if defined(CONFIG_SPD_EEPROM)
+/* Determine DDR configuration from I2C interface
+ */
+#define SPD_EEPROM_ADDRESS	0x51	/* DDR SODIMM */
+#else
+/* Manually set up DDR parameters
+ */
+#define CFG_DDR_SIZE		64	/* MB */
+#define CFG_DDR_CS0_CONFIG	0x80840101
+#define CFG_DDR_TIMING_0	0x00220802
+#define CFG_DDR_TIMING_1	0x3935d322
+#define CFG_DDR_TIMING_2	0x0f9048ca
+#define CFG_DDR_TIMING_3	0x00000000
+#define CFG_DDR_CLK_CNTL	0x02000000
+#define CFG_DDR_MODE		0x44400232
+#define CFG_DDR_MODE2		0x8000c000
+#define CFG_DDR_INTERVAL	0x03200064
+#define CFG_DDR_CS0_BNDS	0x00000003
+#define CFG_DDR_SDRAM_CFG	0x43080000
+#define CFG_DDR_SDRAM_CFG2	0x00401000
+#endif
+
+/*
+ * Memory test
+ */
+#undef CFG_DRAM_TEST		/* memory test, takes time */
+#define CFG_MEMTEST_START	0x00030000	/* memtest region */
+#define CFG_MEMTEST_END		0x03f00000
+
+/*
+ * The reserved memory
+ */
+#define CFG_MONITOR_BASE	TEXT_BASE	/* start of monitor */
+
+#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
+#define CFG_RAMBOOT
+#else
+#undef  CFG_RAMBOOT
+#endif
+
+#define CFG_MONITOR_LEN		(256 * 1024)	/* Reserve 256 kB for Mon */
+#define CFG_MALLOC_LEN		(128 * 1024)	/* Reserved for malloc */
+
+/*
+ * Initial RAM Base Address Setup
+ */
+#define CFG_INIT_RAM_LOCK	1
+#define CFG_INIT_RAM_ADDR	0xE6000000	/* Initial RAM address */
+#define CFG_INIT_RAM_END	0x1000		/* End of used area in RAM */
+#define CFG_GBL_DATA_SIZE	0x100		/* num bytes initial data */
+#define CFG_GBL_DATA_OFFSET	(CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+/*
+ * Local Bus Configuration & Clock Setup
+ */
+#define CFG_LCRR		(LCRR_DBYP | LCRR_CLKDIV_2)
+#define CFG_LBC_LBCR		0x00000000
+
+/*
+ * FLASH on the Local Bus
+ */
+#define CFG_FLASH_CFI		/* use the Common Flash Interface */
+#define CFG_FLASH_CFI_DRIVER	/* use the CFI driver */
+#define CFG_FLASH_BASE		0xFE000000	/* FLASH base address */
+#define CFG_FLASH_SIZE		16	/* FLASH size is 16M */
+
+#define CFG_LBLAWBAR0_PRELIM	CFG_FLASH_BASE	/* Window base at flash base */
+#define CFG_LBLAWAR0_PRELIM	0x80000018	/* 32MB window size */
+
+#define CFG_BR0_PRELIM	(CFG_FLASH_BASE |	/* Flash Base address */ \
+			(2 << BR_PS_SHIFT) |	/* 16 bit port size */ \
+			BR_V)			/* valid */
+#define CFG_OR0_PRELIM		0xfe006ff7	/* 16MB Flash size */
+
+#define CFG_MAX_FLASH_BANKS	1		/* number of banks */
+#define CFG_MAX_FLASH_SECT	128		/* sectors per device */
+
+#undef CFG_FLASH_CHECKSUM
+
+/*
+ * SDRAM on the Local Bus
+ */
+#undef CFG_LB_SDRAM		/* The board has not SRDAM on local bus */
+
+#ifdef CFG_LB_SDRAM
+#define CFG_LBC_SDRAM_BASE	0xF0000000	/* SDRAM base address */
+#define CFG_LBC_SDRAM_SIZE	64		/* LBC SDRAM is 64MB */
+
+#define CFG_LBLAWBAR2_PRELIM	CFG_LBC_SDRAM_BASE
+#define CFG_LBLAWAR2_PRELIM	0x80000019	/* 64MB */
+
+/*local bus BR2, OR2 definition for SDRAM if soldered on the EPB board */
+/*
+ * Base Register 2 and Option Register 2 configure SDRAM.
+ * The SDRAM base address, CFG_LBC_SDRAM_BASE, is 0xf0000000.
+ *
+ * For BR2, need:
+ *    Base address of 0xf0000000 = BR[0:16] = 1111 0000 0000 0000 0
+ *    port size = 32-bits = BR2[19:20] = 11
+ *    no parity checking = BR2[21:22] = 00
+ *    SDRAM for MSEL = BR2[24:26] = 011
+ *    Valid = BR[31] = 1
+ *
+ * 0    4    8    12   16   20   24   28
+ * 1111 0000 0000 0000 0001 1000 0110 0001 = f0001861
+ *
+ * CFG_LBC_SDRAM_BASE should be masked and OR'ed into
+ * the top 17 bits of BR2.
+ */
+
+#define CFG_BR2_PRELIM	0xf0001861	/*Port size=32bit, MSEL=SDRAM */
+
+/*
+ * The SDRAM size in MB, CFG_LBC_SDRAM_SIZE, is 64.
+ *
+ * For OR2, need:
+ *    64MB mask for AM, OR2[0:7] = 1111 1100
+ *                 XAM, OR2[17:18] = 11
+ *    9 columns OR2[19-21] = 010
+ *    13 rows   OR2[23-25] = 100
+ *    EAD set for extra time OR[31] = 1
+ *
+ * 0    4    8    12   16   20   24   28
+ * 1111 1100 0000 0000 0110 1001 0000 0001 = fc006901
+ */
+
+#define CFG_OR2_PRELIM	0xfc006901
+
+#define CFG_LBC_LSRT	0x32000000	/* LB sdram refresh timer, about 6us */
+#define CFG_LBC_MRTPR	0x20000000	/* LB refresh timer prescal, 266MHz/32 */
+
+/*
+ * LSDMR masks
+ */
+#define CFG_LBC_LSDMR_OP_NORMAL	(0 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_ARFRSH	(1 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_SRFRSH	(2 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_MRW	(3 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_PRECH	(4 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_PCHALL	(5 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_ACTBNK	(6 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_RWINV	(7 << (31 - 4))
+
+#define CFG_LBC_LSDMR_COMMON	0x0063b723
+
+/*
+ * SDRAM Controller configuration sequence.
+ */
+#define CFG_LBC_LSDMR_1		( CFG_LBC_LSDMR_COMMON \
+				| CFG_LBC_LSDMR_OP_PCHALL)
+#define CFG_LBC_LSDMR_2		( CFG_LBC_LSDMR_COMMON \
+				| CFG_LBC_LSDMR_OP_ARFRSH)
+#define CFG_LBC_LSDMR_3		( CFG_LBC_LSDMR_COMMON \
+				| CFG_LBC_LSDMR_OP_ARFRSH)
+#define CFG_LBC_LSDMR_4		( CFG_LBC_LSDMR_COMMON \
+				| CFG_LBC_LSDMR_OP_MRW)
+#define CFG_LBC_LSDMR_5		( CFG_LBC_LSDMR_COMMON \
+				| CFG_LBC_LSDMR_OP_NORMAL)
+
+#endif
+
+/*
+ * Windows to access PIB via local bus
+ */
+#define CFG_LBLAWBAR3_PRELIM	0xf8008000	/* windows base 0xf8008000 */
+#define CFG_LBLAWAR3_PRELIM	0x8000000f	/* windows size 64KB */
+
+/*
+ * Serial Port
+ */
+#define CONFIG_CONS_INDEX	1
+#undef CONFIG_SERIAL_SOFTWARE_FIFO
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+#define CFG_NS16550_REG_SIZE	1
+#define CFG_NS16550_CLK		get_bus_freq(0)
+
+#define CFG_BAUDRATE_TABLE  \
+	{300, 600, 1200, 2400, 4800, 9600, 19200, 38400,115200}
+
+#define CFG_NS16550_COM1	(CFG_IMMR+0x4500)
+#define CFG_NS16550_COM2	(CFG_IMMR+0x4600)
+
+#define CONFIG_CMDLINE_EDITING	1	/* add command line history */
+/* Use the HUSH parser */
+#define CFG_HUSH_PARSER
+#ifdef CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2 "> "
+#endif
+
+/* pass open firmware flat tree */
+#define CONFIG_OF_LIBFDT	1
+#define CONFIG_OF_BOARD_SETUP	1
+
+#define OF_CPU			"PowerPC,8323@0"
+#define OF_SOC			"soc8323@e0000000"
+#define OF_QE			"qe@e0100000"
+#define OF_TBCLK		(bd->bi_busfreq / 4)
+#define OF_STDOUT_PATH		"/soc8323@e0000000/serial@4500"
+
+/* I2C */
+#define CONFIG_HARD_I2C		/* I2C with hardware support */
+#undef CONFIG_SOFT_I2C		/* I2C bit-banged */
+#define CONFIG_FSL_I2C
+#define CFG_I2C_SPEED	400000	/* I2C speed and slave address */
+#define CFG_I2C_SLAVE	0x7F
+#define CFG_I2C_NOPROBES	{0x51}	/* Don't probe these addrs */
+#define CFG_I2C_OFFSET	0x3000
+
+/*
+ * Config on-board RTC
+ */
+#define CONFIG_RTC_DS1374		/* use ds1374 rtc via i2c */
+#define CFG_I2C_RTC_ADDR	0x68	/* at address 0x68 */
+
+/*
+ * General PCI
+ * Addresses are mapped 1-1.
+ */
+#define CFG_PCI1_MEM_BASE	0x80000000
+#define CFG_PCI1_MEM_PHYS	CFG_PCI1_MEM_BASE
+#define CFG_PCI1_MEM_SIZE	0x10000000	/* 256M */
+#define CFG_PCI1_MMIO_BASE	0x90000000
+#define CFG_PCI1_MMIO_PHYS	CFG_PCI1_MMIO_BASE
+#define CFG_PCI1_MMIO_SIZE	0x10000000	/* 256M */
+#define CFG_PCI1_IO_BASE		0xd0000000
+#define CFG_PCI1_IO_PHYS		CFG_PCI1_IO_BASE
+#define CFG_PCI1_IO_SIZE		0x04000000	/* 64M */
+
+#ifdef CONFIG_PCI
+
+#define CONFIG_NET_MULTI
+#define CONFIG_PCI_PNP		/* do pci plug-and-play */
+
+#undef CONFIG_EEPRO100
+#undef CONFIG_PCI_SCAN_SHOW	/* show pci devices on startup */
+#define CFG_PCI_SUBSYS_VENDORID	0x1957	/* Freescale */
+
+#endif	/* CONFIG_PCI */
+
+
+#ifndef CONFIG_NET_MULTI
+#define CONFIG_NET_MULTI	1
+#endif
+
+/*
+ * QE UEC ethernet configuration
+ */
+#define CONFIG_UEC_ETH
+#define CONFIG_ETHPRIME		"Freescale GETH"
+
+#define CONFIG_UEC_ETH1		/* ETH3 */
+
+#ifdef CONFIG_UEC_ETH1
+#define CFG_UEC1_UCC_NUM	2	/* UCC3 */
+#define CFG_UEC1_RX_CLK		QE_CLK9
+#define CFG_UEC1_TX_CLK		QE_CLK10
+#define CFG_UEC1_ETH_TYPE	FAST_ETH
+#define CFG_UEC1_PHY_ADDR	4
+#define CFG_UEC1_INTERFACE_MODE	ENET_100_MII
+#endif
+
+#define CONFIG_UEC_ETH2		/* ETH4 */
+
+#ifdef CONFIG_UEC_ETH2
+#define CFG_UEC2_UCC_NUM	1	/* UCC2 */
+#define CFG_UEC2_RX_CLK		QE_CLK16
+#define CFG_UEC2_TX_CLK		QE_CLK3
+#define CFG_UEC2_ETH_TYPE	FAST_ETH
+#define CFG_UEC2_PHY_ADDR	0
+#define CFG_UEC2_INTERFACE_MODE	ENET_100_MII
+#endif
+
+/*
+ * Environment
+ */
+#ifndef CFG_RAMBOOT
+	#define CFG_ENV_IS_IN_FLASH	1
+	#define CFG_ENV_ADDR		(CFG_MONITOR_BASE + 0x40000)
+	#define CFG_ENV_SECT_SIZE	0x40000	/* 256K(one sector) for env */
+	#define CFG_ENV_SIZE		0x2000
+#else
+	#define CFG_NO_FLASH		1	/* Flash is not usable now */
+	#define CFG_ENV_IS_NOWHERE	1	/* Store ENV in memory only */
+	#define CFG_ENV_ADDR		(CFG_MONITOR_BASE - 0x1000)
+	#define CFG_ENV_SIZE		0x2000
+#endif
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download */
+#define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change */
+
+/*
+ * BOOTP options
+ */
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+
+/*
+ * Command line configuration.
+ */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_ASKENV
+
+#if defined(CONFIG_PCI)
+	#define CONFIG_CMD_PCI
+#endif
+#if defined(CFG_RAMBOOT)
+	#undef CONFIG_CMD_ENV
+	#undef CONFIG_CMD_LOADS
+#endif
+
+#undef CONFIG_WATCHDOG		/* watchdog disabled */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP		/* undef to save memory */
+#define CFG_LOAD_ADDR		0x2000000	/* default load address */
+#define CFG_PROMPT		"=> "	/* Monitor Command Prompt */
+
+#if (CONFIG_CMD_KGDB)
+	#define CFG_CBSIZE	1024	/* Console I/O Buffer Size */
+#else
+	#define CFG_CBSIZE	256	/* Console I/O Buffer Size */
+#endif
+
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)	/* Print Buffer Size */
+#define CFG_MAXARGS	16		/* max number of command args */
+#define CFG_BARGSIZE	CFG_CBSIZE	/* Boot Argument Buffer Size */
+#define CFG_HZ		1000		/* decrementer freq: 1ms ticks */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux */
+
+/*
+ * Core HID Setup
+ */
+#define CFG_HID0_INIT		0x000000000
+#define CFG_HID0_FINAL		HID0_ENABLE_MACHINE_CHECK
+#define CFG_HID2		HID2_HBE
+
+/*
+ * Cache Config
+ */
+#define CFG_DCACHE_SIZE		16384
+#define CFG_CACHELINE_SIZE	32
+#if defined(CONFIG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT	5	/*log base 2 of the above value */
+#endif
+
+/*
+ * MMU Setup
+ */
+
+/* DDR: cache cacheable */
+#define CFG_IBAT0L	(CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U	(CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+#define CFG_DBAT0L	CFG_IBAT0L
+#define CFG_DBAT0U	CFG_IBAT0U
+
+/* IMMRBAR & PCI IO: cache-inhibit and guarded */
+#define CFG_IBAT1L	(CFG_IMMR | BATL_PP_10 | \
+			BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CFG_IBAT1U	(CFG_IMMR | BATU_BL_4M | BATU_VS | BATU_VP)
+#define CFG_DBAT1L	CFG_IBAT1L
+#define CFG_DBAT1U	CFG_IBAT1U
+
+/* FLASH: icache cacheable, but dcache-inhibit and guarded */
+#define CFG_IBAT2L	(CFG_FLASH_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT2U	(CFG_FLASH_BASE | BATU_BL_32M | BATU_VS | BATU_VP)
+#define CFG_DBAT2L	(CFG_FLASH_BASE | BATL_PP_10 | \
+			BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CFG_DBAT2U	CFG_IBAT2U
+
+#define CFG_IBAT3L	(0)
+#define CFG_IBAT3U	(0)
+#define CFG_DBAT3L	CFG_IBAT3L
+#define CFG_DBAT3U	CFG_IBAT3U
+
+/* Stack in dcache: cacheable, no memory coherence */
+#define CFG_IBAT4L	(CFG_INIT_RAM_ADDR | BATL_PP_10)
+#define CFG_IBAT4U	(CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+#define CFG_DBAT4L	CFG_IBAT4L
+#define CFG_DBAT4U	CFG_IBAT4U
+
+#ifdef CONFIG_PCI
+/* PCI MEM space: cacheable */
+#define CFG_IBAT5L	(CFG_PCI1_MEM_PHYS | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT5U	(CFG_PCI1_MEM_PHYS | BATU_BL_256M | BATU_VS | BATU_VP)
+#define CFG_DBAT5L	CFG_IBAT5L
+#define CFG_DBAT5U	CFG_IBAT5U
+/* PCI MMIO space: cache-inhibit and guarded */
+#define CFG_IBAT6L	(CFG_PCI1_MMIO_PHYS | BATL_PP_10 | \
+			BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CFG_IBAT6U	(CFG_PCI1_MMIO_PHYS | BATU_BL_256M | BATU_VS | BATU_VP)
+#define CFG_DBAT6L	CFG_IBAT6L
+#define CFG_DBAT6U	CFG_IBAT6U
+#else
+#define CFG_IBAT5L	(0)
+#define CFG_IBAT5U	(0)
+#define CFG_IBAT6L	(0)
+#define CFG_IBAT6U	(0)
+#define CFG_DBAT5L	CFG_IBAT5L
+#define CFG_DBAT5U	CFG_IBAT5U
+#define CFG_DBAT6L	CFG_IBAT6L
+#define CFG_DBAT6U	CFG_IBAT6U
+#endif
+
+/* Nothing in BAT7 */
+#define CFG_IBAT7L	(0)
+#define CFG_IBAT7U	(0)
+#define CFG_DBAT7L	CFG_IBAT7L
+#define CFG_DBAT7U	CFG_IBAT7U
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01	/* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM	0x02	/* Software reboot */
+
+#if (CONFIG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE	230400	/* speed of kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX	2	/* which serial port to use */
+#endif
+
+/*
+ * Environment Configuration
+ */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_ETHADDR	00:04:9f:ef:03:01
+#define CONFIG_HAS_ETH1				/* add support for "eth1addr" */
+#define CONFIG_ETH1ADDR	00:04:9f:ef:03:02
+
+#define CONFIG_IPADDR		10.0.0.2
+#define CONFIG_SERVERIP		10.0.0.1
+#define CONFIG_GATEWAYIP	10.0.0.1
+#define CONFIG_NETMASK		255.0.0.0
+#define CONFIG_NETDEV		eth1
+
+#define CONFIG_HOSTNAME		mpc8323erdb
+#define CONFIG_ROOTPATH		/nfsroot
+#define CONFIG_RAMDISKFILE	rootfs.ext2.gz.uboot
+#define CONFIG_BOOTFILE		uImage
+#define CONFIG_UBOOTPATH	u-boot.bin	/* U-Boot image on TFTP server */
+#define CONFIG_FDTFILE		mpc832x_rdb.dtb
+
+#define CONFIG_LOADADDR		200000	/* default location for tftp and bootm */
+#define CONFIG_BOOTDELAY	-1	/* -1 disables auto-boot */
+#define CONFIG_BAUDRATE		115200
+
+#define XMK_STR(x)	#x
+#define MK_STR(x)	XMK_STR(x)
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"netdev=" MK_STR(CONFIG_NETDEV) "\0"				\
+	"uboot=" MK_STR(CONFIG_UBOOTPATH) "\0"				\
+	"tftpflash=tftp $loadaddr $uboot;"				\
+		"protect off " MK_STR(TEXT_BASE) " +$filesize; "	\
+		"erase " MK_STR(TEXT_BASE) " +$filesize; "		\
+		"cp.b $loadaddr " MK_STR(TEXT_BASE) " $filesize; "	\
+		"protect on " MK_STR(TEXT_BASE) " +$filesize; "		\
+		"cmp.b $loadaddr " MK_STR(TEXT_BASE) " $filesize\0"	\
+	"fdtaddr=400000\0"						\
+	"fdtfile=" MK_STR(CONFIG_FDTFILE) "\0"				\
+	"ramdiskaddr=1000000\0"						\
+	"ramdiskfile=" MK_STR(CONFIG_RAMDISKFILE) "\0"			\
+	"console=ttyS0\0"						\
+	"setbootargs=setenv bootargs "					\
+		"root=$rootdev rw console=$console,$baudrate $othbootargs\0" \
+	"setipargs=setenv bootargs nfsroot=$serverip:$rootpath "	\
+		"ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \
+		"root=$rootdev rw console=$console,$baudrate $othbootargs\0"
+
+#define CONFIG_NFSBOOTCOMMAND						\
+	"setenv rootdev /dev/nfs;"					\
+	"run setbootargs;"						\
+	"run setipargs;"						\
+	"tftp $loadaddr $bootfile;"					\
+	"tftp $fdtaddr $fdtfile;"					\
+	"bootm $loadaddr - $fdtaddr"
+
+#define CONFIG_RAMBOOTCOMMAND						\
+	"setenv rootdev /dev/ram;"					\
+	"run setbootargs;"						\
+	"tftp $ramdiskaddr $ramdiskfile;"				\
+	"tftp $loadaddr $bootfile;"					\
+	"tftp $fdtaddr $fdtfile;"					\
+	"bootm $loadaddr $ramdiskaddr $fdtaddr"
+
+#undef MK_STR
+#undef XMK_STR
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/MPC8349ITX.h b/include/configs/MPC8349ITX.h
index 121ff06dc5cecb4c7a474ffe11b2fc32dbdf96eb..44649d05090b9a2cfeb7b84c6cdc699c26625334 100644
--- a/include/configs/MPC8349ITX.h
+++ b/include/configs/MPC8349ITX.h
@@ -289,6 +289,7 @@ boards, we say we have two, but don't display a message if we find only one. */
 #define CFG_BAUDRATE_TABLE  \
 	{300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 115200}
 
+#define CONFIG_CONSOLE		ttyS0
 #define CONFIG_BAUDRATE		115200
 
 #define CFG_NS16550_COM1	(CFG_IMMR + 0x4500)
@@ -408,6 +409,7 @@ boards, we say we have two, but don't display a message if we find only one. */
   #define CFG_ENV_SIZE		0x2000
 #else
   #define CFG_NO_FLASH		/* Flash is not usable now */
+  #undef  CFG_FLASH_CFI_DRIVER
   #define CFG_ENV_IS_NOWHERE	/* Store ENV in memory only */
   #define CFG_ENV_ADDR		(CFG_MONITOR_BASE - 0x1000)
   #define CFG_ENV_SIZE		0x2000
@@ -450,9 +452,7 @@ boards, we say we have two, but don't display a message if we find only one. */
     #define CONFIG_CMD_I2C
 #endif
 
-
 /* Watchdog */
-
 #undef CONFIG_WATCHDOG		/* watchdog disabled */
 
 /*
@@ -673,9 +673,10 @@ boards, we say we have two, but don't display a message if we find only one. */
 	" ip=" MK_STR(CONFIG_IPADDR) ":" MK_STR(CONFIG_SERVERIP) ":" 	\
 		MK_STR(CONFIG_GATEWAYIP) ":" MK_STR(CONFIG_NETMASK) ":" \
 		MK_STR(CONFIG_HOSTNAME) ":" MK_STR(CONFIG_NETDEV) ":off" \
-	" console=ttyS0," MK_STR(CONFIG_BAUDRATE)
+	" console=" MK_STR(CONFIG_CONSOLE) "," MK_STR(CONFIG_BAUDRATE)
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
+	"console=" MK_STR(CONFIG_CONSOLE) "\0" 				\
 	"netdev=" MK_STR(CONFIG_NETDEV) "\0" 				\
 	"uboot=" MK_STR(CONFIG_UBOOTPATH) "\0" 				\
 	"tftpflash=tftpboot $loadaddr $uboot; " 			\
diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h
index 888af530c24e88b09a585505da389274e0a6d774..64dcbd010934d062f17b2677fb020e6ecfaa41f8 100644
--- a/include/configs/MPC8641HPCN.h
+++ b/include/configs/MPC8641HPCN.h
@@ -338,6 +338,17 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 #undef CONFIG_EEPRO100
 #undef CONFIG_TULIP
 
+/************************************************************
+ * USB support
+ ************************************************************/
+#define CONFIG_PCI_OHCI		1
+#define CONFIG_USB_OHCI_NEW		1
+#define CONFIG_USB_KEYBOARD	1
+#define CFG_DEVICE_DEREGISTER
+#define CFG_USB_EVENT_POLL	1
+#define CFG_USB_OHCI_SLOT_NAME 	"ohci_pci"
+#define CFG_USB_OHCI_MAX_ROOT_PORTS 15
+
 #if !defined(CONFIG_PCI_PNP)
     #define PCI_ENET0_IOADDR	0xe0000000
     #define PCI_ENET0_MEMADDR	0xe0000000
diff --git a/include/configs/TQM5200.h b/include/configs/TQM5200.h
index 63d77e2941aa618bf0cfd6fbb713769594c1c8b6..8360d8c0d7cbd2f89d346e4c1c034ee7ec325070 100644
--- a/include/configs/TQM5200.h
+++ b/include/configs/TQM5200.h
@@ -130,8 +130,18 @@
 
 /* USB */
 #if defined(CONFIG_STK52XX) || defined(CONFIG_FO300)
-#define CONFIG_USB_OHCI
+#define CONFIG_USB_OHCI_NEW
+#define ADD_USB_CMD		CFG_CMD_USB | CFG_CMD_FAT
 #define CONFIG_USB_STORAGE
+
+#undef CFG_USB_OHCI_BOARD_INIT
+#define CFG_USB_OHCI_CPU_INIT
+#define CFG_USB_OHCI_REGS_BASE	MPC5XXX_USB
+#define CFG_USB_OHCI_SLOT_NAME	"mpc5200"
+#define CFG_USB_OHCI_MAX_ROOT_PORTS	15
+
+#else
+#define ADD_USB_CMD		0
 #endif
 
 #ifndef CONFIG_CAM5200
diff --git a/include/configs/TQM834x.h b/include/configs/TQM834x.h
index c3efb7bb9c7a5cf3b61281e3b08268e7bfac9269..661712b227b9e2ff7144b43cbd5818b18d20ea34 100644
--- a/include/configs/TQM834x.h
+++ b/include/configs/TQM834x.h
@@ -28,9 +28,6 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
-#define DEBUG
-#undef DEBUG
-
 /*
  * High Level Configuration Options
  */
diff --git a/include/configs/davinci_dvevm.h b/include/configs/davinci_dvevm.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ecd0595a2040282322b83309bd09f35ce3c9840
--- /dev/null
+++ b/include/configs/davinci_dvevm.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+#include <asm/sizes.h>
+
+/*
+ * Define this to make U-Boot skip low level initialization when loaded
+ * by initial bootloader. Not required by NAND U-Boot version but IS
+ * required for a NOR version used to burn the real NOR U-Boot into
+ * NOR Flash. NAND and NOR support for DaVinci chips is mutually exclusive
+ * so it is NOT possible to build a U-Boot with both NAND and NOR routines.
+ * NOR U-Boot is loaded directly from Flash so it must perform all the
+ * low level initialization itself. NAND version is loaded by an initial
+ * bootloader (UBL in TI-ese) that performs such an initialization so it's
+ * skipped in NAND version. The third DaVinci boot mode loads a bootloader
+ * via UART0 and that bootloader in turn loads and runs U-Boot (or whatever)
+ * performing low level init prior to loading. All that means we can NOT use
+ * NAND version to put U-Boot into NOR because it doesn't have NOR support and
+ * we can NOT use NOR version because it performs low level initialization
+ * effectively destroying itself in DDR memory. That's why a separate NOR
+ * version with this define is needed. It is loaded via UART, then one uses
+ * it to somehow download a proper NOR version built WITHOUT this define to
+ * RAM (tftp?) and burn it to NOR Flash. I would be probably able to squeeze
+ * NOR support into the initial bootloader so it won't be needed but DaVinci
+ * static RAM might be too small for this (I have something like 2Kbytes left
+ * as of now, without NOR support) so this might've not happened...
+ *
+#define CONFIG_NOR_UART_BOOT
+ */
+
+/*=======*/
+/* Board */
+/*=======*/
+#define DV_EVM
+#define CFG_NAND_SMALLPAGE
+#define CFG_USE_NOR
+/*===================*/
+/* SoC Configuration */
+/*===================*/
+#define CONFIG_ARM926EJS			/* arm926ejs CPU core */
+#define CONFIG_SYS_CLK_FREQ	297000000	/* Arm Clock frequency */
+#define CFG_TIMERBASE		0x01c21400	/* use timer 0 */
+#define CFG_HZ_CLOCK		27000000	/* Timer Input clock freq */
+#define CFG_HZ			1000
+/*====================================================*/
+/* EEPROM definitions for Atmel 24C256BN SEEPROM chip */
+/* on Sonata/DV_EVM board. No EEPROM on schmoogie.    */
+/*====================================================*/
+#define CFG_I2C_EEPROM_ADDR_LEN		2
+#define CFG_I2C_EEPROM_ADDR		0x50
+#define CFG_EEPROM_PAGE_WRITE_BITS	6
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	20
+/*=============*/
+/* Memory Info */
+/*=============*/
+#define CFG_MALLOC_LEN		(0x10000 + 128*1024)	/* malloc() len */
+#define CFG_GBL_DATA_SIZE	128		/* reserved for initial data */
+#define CFG_MEMTEST_START	0x80000000	/* memtest start address */
+#define CFG_MEMTEST_END		0x81000000	/* 16MB RAM test */
+#define CONFIG_NR_DRAM_BANKS	1		/* we have 1 bank of DRAM */
+#define CONFIG_STACKSIZE	(256*1024)	/* regular stack */
+#define PHYS_SDRAM_1		0x80000000	/* DDR Start */
+#define PHYS_SDRAM_1_SIZE	0x10000000	/* DDR size 256MB */
+#define DDR_8BANKS				/* 8-bank DDR2 (256MB) */
+/*====================*/
+/* Serial Driver info */
+/*====================*/
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+#define CFG_NS16550_REG_SIZE	4		/* NS16550 register size */
+#define CFG_NS16550_COM1	0x01c20000	/* Base address of UART0 */
+#define CFG_NS16550_CLK		27000000	/* Input clock to NS16550 */
+#define CONFIG_CONS_INDEX	1		/* use UART0 for console */
+#define CONFIG_BAUDRATE		115200		/* Default baud rate */
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+/*===================*/
+/* I2C Configuration */
+/*===================*/
+#define CONFIG_HARD_I2C
+#define CONFIG_DRIVER_DAVINCI_I2C
+#define CFG_I2C_SPEED		80000	/* 100Kbps won't work, silicon bug */
+#define CFG_I2C_SLAVE		10	/* Bogus, master-only in U-Boot */
+/*==================================*/
+/* Network & Ethernet Configuration */
+/*==================================*/
+#define CONFIG_DRIVER_TI_EMAC
+#define CONFIG_MII
+#define CONFIG_BOOTP_DEFAULT
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+#define CONFIG_BOOTP_SEND_HOSTNAME
+#define CONFIG_NET_RETRY_COUNT	10
+/*=====================*/
+/* Flash & Environment */
+/*=====================*/
+#ifdef CFG_USE_NAND
+#undef CFG_ENV_IS_IN_FLASH
+#define CFG_NO_FLASH
+#define CFG_ENV_IS_IN_NAND		/* U-Boot env in NAND Flash  */
+#ifdef CFG_NAND_SMALLPAGE
+#define CFG_ENV_SECT_SIZE	512	/* Env sector Size */
+#define CFG_ENV_SIZE		SZ_16K
+#else
+#define CFG_ENV_SECT_SIZE	2048	/* Env sector Size */
+#define CFG_ENV_SIZE		SZ_128K
+#endif
+#define CONFIG_SKIP_LOWLEVEL_INIT	/* U-Boot is loaded by a bootloader */
+#define CONFIG_SKIP_RELOCATE_UBOOT	/* to a proper address, init done */
+#define CFG_NAND_BASE		0x02000000
+#define CFG_NAND_HW_ECC
+#define CFG_MAX_NAND_DEVICE	1	/* Max number of NAND devices */
+#define NAND_MAX_CHIPS		1
+#define CFG_ENV_OFFSET		0x0	/* Block 0--not used by bootcode */
+#define DEF_BOOTM		""
+#elif defined(CFG_USE_NOR)
+#ifdef CONFIG_NOR_UART_BOOT
+#define CONFIG_SKIP_LOWLEVEL_INIT	/* U-Boot is loaded by a bootloader */
+#define CONFIG_SKIP_RELOCATE_UBOOT	/* to a proper address, init done */
+#else
+#undef CONFIG_SKIP_LOWLEVEL_INIT
+#undef CONFIG_SKIP_RELOCATE_UBOOT
+#endif
+#define CFG_ENV_IS_IN_FLASH
+#undef CFG_NO_FLASH
+#define CFG_FLASH_CFI_DRIVER
+#define CFG_FLASH_CFI
+#define CFG_MAX_FLASH_BANKS	1		/* max number of flash banks */
+#define CFG_FLASH_SECT_SZ	0x10000		/* 64KB sect size AMD Flash */
+#define CFG_ENV_OFFSET		(CFG_FLASH_SECT_SZ*3)
+#define PHYS_FLASH_1		0x02000000	/* CS2 Base address 	 */
+#define CFG_FLASH_BASE		PHYS_FLASH_1	/* Flash Base for U-Boot */
+#define PHYS_FLASH_SIZE		0x2000000	/* Flash size 32MB 	 */
+#define CFG_MAX_FLASH_SECT	(PHYS_FLASH_SIZE/CFG_FLASH_SECT_SZ)
+#define CFG_ENV_SECT_SIZE	CFG_FLASH_SECT_SZ	/* Env sector Size */
+#endif
+/*==============================*/
+/* U-Boot general configuration */
+/*==============================*/
+#undef 	CONFIG_USE_IRQ			/* No IRQ/FIQ in U-Boot */
+#define CONFIG_MISC_INIT_R
+#undef CONFIG_BOOTDELAY
+#define CONFIG_BOOTFILE		"uImage"	/* Boot file name */
+#define CFG_PROMPT		"U-Boot > "	/* Monitor Command Prompt */
+#define CFG_CBSIZE		1024		/* Console I/O Buffer Size  */
+#define CFG_PBSIZE		(CFG_CBSIZE+sizeof(CFG_PROMPT)+16)	/* Print buffer sz */
+#define CFG_MAXARGS		16		/* max number of command args */
+#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR		0x80700000	/* default Linux kernel load address */
+#define CONFIG_VERSION_VARIABLE
+#define CONFIG_AUTO_COMPLETE		/* Won't work with hush so far, may be later */
+#define CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2	"> "
+#define CONFIG_CMDLINE_EDITING
+#define CFG_LONGHELP
+#define CONFIG_CRC32_VERIFY
+#define CONFIG_MX_CYCLIC
+/*===================*/
+/* Linux Information */
+/*===================*/
+#define LINUX_BOOT_PARAM_ADDR	0x80000100
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTARGS		"mem=120M console=ttyS0,115200n8 root=/dev/hda1 rw noinitrd ip=dhcp"
+#define CONFIG_BOOTCOMMAND	"setenv setboot setenv bootargs \\$(bootargs) video=dm64xxfb:output=\\$(videostd);run setboot; bootm 0x2050000"
+/*=================*/
+/* U-Boot commands */
+/*=================*/
+#include <config_cmd_default.h>
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_EEPROM
+#undef CONFIG_CMD_BDI
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_SETGETDCR
+#ifdef CFG_USE_NAND
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_IMLS
+#define CONFIG_CMD_NAND
+#elif defined(CFG_USE_NOR)
+#define CONFIG_CMD_JFFS2
+#else
+#error "Either CFG_USE_NAND or CFG_USE_NOR _MUST_ be defined !!!"
+#endif
+/*=======================*/
+/* KGDB support (if any) */
+/*=======================*/
+#ifdef CONFIG_CMD_KGDB
+#define CONFIG_KGDB_BAUDRATE	115200	/* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX	1	/* which serial port to use */
+#endif
+#endif /* __CONFIG_H */
diff --git a/include/configs/davinci_schmoogie.h b/include/configs/davinci_schmoogie.h
new file mode 100644
index 0000000000000000000000000000000000000000..96c9a30147828810e780029abd4427696728d923
--- /dev/null
+++ b/include/configs/davinci_schmoogie.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+#include <asm/sizes.h>
+
+/*=======*/
+/* Board */
+/*=======*/
+#define SCHMOOGIE
+#define CFG_NAND_LARGEPAGE
+#define CFG_USE_NAND
+/*===================*/
+/* SoC Configuration */
+/*===================*/
+#define CONFIG_ARM926EJS			/* arm926ejs CPU core */
+#define CONFIG_SYS_CLK_FREQ	297000000	/* Arm Clock frequency */
+#define CFG_TIMERBASE		0x01c21400	/* use timer 0 */
+#define CFG_HZ_CLOCK		27000000	/* Timer Input clock freq */
+#define CFG_HZ			1000
+/*=============*/
+/* Memory Info */
+/*=============*/
+#define CFG_MALLOC_LEN		(0x10000 + 256*1024)	/* malloc() len */
+#define CFG_GBL_DATA_SIZE	128		/* reserved for initial data */
+#define CFG_MEMTEST_START	0x80000000	/* memtest start address */
+#define CFG_MEMTEST_END		0x81000000	/* 16MB RAM test */
+#define CONFIG_NR_DRAM_BANKS	1		/* we have 1 bank of DRAM */
+#define CONFIG_STACKSIZE	(256*1024)	/* regular stack */
+#define PHYS_SDRAM_1		0x80000000	/* DDR Start */
+#define PHYS_SDRAM_1_SIZE	0x08000000	/* DDR size 128MB */
+#define DDR_4BANKS				/* 4-bank DDR2 (128MB) */
+/*====================*/
+/* Serial Driver info */
+/*====================*/
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+#define CFG_NS16550_REG_SIZE	4		/* NS16550 register size */
+#define CFG_NS16550_COM1	0x01c20000	/* Base address of UART0 */
+#define CFG_NS16550_CLK		27000000	/* Input clock to NS16550 */
+#define CONFIG_CONS_INDEX	1		/* use UART0 for console */
+#define CONFIG_BAUDRATE		115200		/* Default baud rate */
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+/*===================*/
+/* I2C Configuration */
+/*===================*/
+#define CONFIG_HARD_I2C
+#define CONFIG_DRIVER_DAVINCI_I2C
+#define CFG_I2C_SPEED		80000	/* 100Kbps won't work, silicon bug */
+#define CFG_I2C_SLAVE		10	/* Bogus, master-only in U-Boot */
+/*==================================*/
+/* Network & Ethernet Configuration */
+/*==================================*/
+#define CONFIG_DRIVER_TI_EMAC
+#define CONFIG_MII
+#define CONFIG_BOOTP_DEFAULT
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+#define CONFIG_BOOTP_SEND_HOSTNAME
+#define CONFIG_NET_RETRY_COUNT	10
+#define CONFIG_OVERWRITE_ETHADDR_ONCE
+/*=====================*/
+/* Flash & Environment */
+/*=====================*/
+#undef CFG_ENV_IS_IN_FLASH
+#define CFG_NO_FLASH
+#define CFG_ENV_IS_IN_NAND		/* U-Boot env in NAND Flash  */
+#define CFG_ENV_SECT_SIZE	2048	/* Env sector Size */
+#define CFG_ENV_SIZE		SZ_128K
+#define CONFIG_SKIP_LOWLEVEL_INIT	/* U-Boot is loaded by a bootloader */
+#define CONFIG_SKIP_RELOCATE_UBOOT	/* to a proper address, init done */
+#define CFG_NAND_BASE		0x02000000
+#define CFG_NAND_HW_ECC
+#define CFG_MAX_NAND_DEVICE	1	/* Max number of NAND devices */
+#define NAND_MAX_CHIPS		1
+#define CFG_ENV_OFFSET		0x0	/* Block 0--not used by bootcode */
+/*=====================*/
+/* Board related stuff */
+/*=====================*/
+#define CONFIG_RTC_DS1307		/* RTC chip on SCHMOOGIE */
+#define CFG_I2C_RTC_ADDR	0x6f	/* RTC chip I2C address */
+#define CONFIG_HAS_UID
+#define CONFIG_UID_DS28CM00		/* Unique ID on SCHMOOGIE */
+#define CFG_UID_ADDR		0x50	/* UID chip I2C address */
+/*==============================*/
+/* U-Boot general configuration */
+/*==============================*/
+#undef 	CONFIG_USE_IRQ			/* No IRQ/FIQ in U-Boot */
+#define CONFIG_MISC_INIT_R
+#undef CONFIG_BOOTDELAY
+#define CONFIG_BOOTFILE		"uImage"	/* Boot file name */
+#define CFG_PROMPT		"U-Boot > "	/* Monitor Command Prompt */
+#define CFG_CBSIZE		1024		/* Console I/O Buffer Size  */
+#define CFG_PBSIZE		(CFG_CBSIZE+sizeof(CFG_PROMPT)+16)	/* Print buffer sz */
+#define CFG_MAXARGS		16		/* max number of command args */
+#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR		0x80700000	/* default Linux kernel load address */
+#define CONFIG_VERSION_VARIABLE
+#define CONFIG_AUTO_COMPLETE		/* Won't work with hush so far, may be later */
+#define CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2	"> "
+#define CONFIG_CMDLINE_EDITING
+#define CFG_LONGHELP
+#define CONFIG_CRC32_VERIFY
+#define CONFIG_MX_CYCLIC
+/*===================*/
+/* Linux Information */
+/*===================*/
+#define LINUX_BOOT_PARAM_ADDR	0x80000100
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTARGS		"mem=56M console=ttyS0,115200n8 root=/dev/hda1 rw noinitrd ip=dhcp"
+#define CONFIG_BOOTCOMMAND	"setenv setboot setenv bootargs \\$(bootargs) video=dm64xxfb:output=\\$(videostd);run setboot"
+/*=================*/
+/* U-Boot commands */
+/*=================*/
+#include <config_cmd_default.h>
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_DATE
+#define CONFIG_CMD_NAND
+#undef CONFIG_CMD_EEPROM
+#undef CONFIG_CMD_BDI
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_SETGETDCR
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_IMLS
+/*=======================*/
+/* KGDB support (if any) */
+/*=======================*/
+#ifdef CONFIG_CMD_KGDB
+#define CONFIG_KGDB_BAUDRATE	115200	/* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX	1	/* which serial port to use */
+#endif
+#endif /* __CONFIG_H */
diff --git a/include/configs/davinci_sonata.h b/include/configs/davinci_sonata.h
new file mode 100644
index 0000000000000000000000000000000000000000..de8c4fac2b00fe2b0d3a5edbbbe5612ce61fc79b
--- /dev/null
+++ b/include/configs/davinci_sonata.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+#include <asm/sizes.h>
+
+/*
+ * Define this to make U-Boot skip low level initialization when loaded
+ * by initial bootloader. Not required by NAND U-Boot version but IS
+ * required for a NOR version used to burn the real NOR U-Boot into
+ * NOR Flash. NAND and NOR support for DaVinci chips is mutually exclusive
+ * so it is NOT possible to build a U-Boot with both NAND and NOR routines.
+ * NOR U-Boot is loaded directly from Flash so it must perform all the
+ * low level initialization itself. NAND version is loaded by an initial
+ * bootloader (UBL in TI-ese) that performs such an initialization so it's
+ * skipped in NAND version. The third DaVinci boot mode loads a bootloader
+ * via UART0 and that bootloader in turn loads and runs U-Boot (or whatever)
+ * performing low level init prior to loading. All that means we can NOT use
+ * NAND version to put U-Boot into NOR because it doesn't have NOR support and
+ * we can NOT use NOR version because it performs low level initialization
+ * effectively destroying itself in DDR memory. That's why a separate NOR
+ * version with this define is needed. It is loaded via UART, then one uses
+ * it to somehow download a proper NOR version built WITHOUT this define to
+ * RAM (tftp?) and burn it to NOR Flash. I would be probably able to squeeze
+ * NOR support into the initial bootloader so it won't be needed but DaVinci
+ * static RAM might be too small for this (I have something like 2Kbytes left
+ * as of now, without NOR support) so this might've not happened...
+ *
+#define CONFIG_NOR_UART_BOOT
+ */
+
+/*=======*/
+/* Board */
+/*=======*/
+#define SONATA_BOARD
+#define CFG_NAND_SMALLPAGE
+#define CFG_USE_NOR
+/*===================*/
+/* SoC Configuration */
+/*===================*/
+#define CONFIG_ARM926EJS			/* arm926ejs CPU core */
+#define CONFIG_SYS_CLK_FREQ	297000000	/* Arm Clock frequency */
+#define CFG_TIMERBASE		0x01c21400	/* use timer 0 */
+#define CFG_HZ_CLOCK		27000000	/* Timer Input clock freq */
+#define CFG_HZ			1000
+/*====================================================*/
+/* EEPROM definitions for Atmel 24C256BN SEEPROM chip */
+/* on Sonata/DV_EVM board. No EEPROM on schmoogie.    */
+/*====================================================*/
+#define CFG_I2C_EEPROM_ADDR_LEN		2
+#define CFG_I2C_EEPROM_ADDR		0x50
+#define CFG_EEPROM_PAGE_WRITE_BITS	6
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	20
+/*=============*/
+/* Memory Info */
+/*=============*/
+#define CFG_MALLOC_LEN		(0x10000 + 128*1024)	/* malloc() len */
+#define CFG_GBL_DATA_SIZE	128		/* reserved for initial data */
+#define CFG_MEMTEST_START	0x80000000	/* memtest start address */
+#define CFG_MEMTEST_END		0x81000000	/* 16MB RAM test */
+#define CONFIG_NR_DRAM_BANKS	1		/* we have 1 bank of DRAM */
+#define CONFIG_STACKSIZE	(256*1024)	/* regular stack */
+#define PHYS_SDRAM_1		0x80000000	/* DDR Start */
+#define PHYS_SDRAM_1_SIZE	0x08000000	/* DDR size 128MB */
+#define DDR_4BANKS				/* 4-bank DDR2 (128MB) */
+/*====================*/
+/* Serial Driver info */
+/*====================*/
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+#define CFG_NS16550_REG_SIZE	4		/* NS16550 register size */
+#define CFG_NS16550_COM1	0x01c20000	/* Base address of UART0 */
+#define CFG_NS16550_CLK		27000000	/* Input clock to NS16550 */
+#define CONFIG_CONS_INDEX	1		/* use UART0 for console */
+#define CONFIG_BAUDRATE		115200		/* Default baud rate */
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+/*===================*/
+/* I2C Configuration */
+/*===================*/
+#define CONFIG_HARD_I2C
+#define CONFIG_DRIVER_DAVINCI_I2C
+#define CFG_I2C_SPEED		80000	/* 100Kbps won't work, silicon bug */
+#define CFG_I2C_SLAVE		10	/* Bogus, master-only in U-Boot */
+/*==================================*/
+/* Network & Ethernet Configuration */
+/*==================================*/
+#define CONFIG_DRIVER_TI_EMAC
+#define CONFIG_MII
+#define CONFIG_BOOTP_DEFAULT
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+#define CONFIG_BOOTP_SEND_HOSTNAME
+#define CONFIG_NET_RETRY_COUNT	10
+/*=====================*/
+/* Flash & Environment */
+/*=====================*/
+#ifdef CFG_USE_NAND
+#undef CFG_ENV_IS_IN_FLASH
+#define CFG_NO_FLASH
+#define CFG_ENV_IS_IN_NAND		/* U-Boot env in NAND Flash  */
+#define CFG_ENV_SECT_SIZE	512	/* Env sector Size */
+#define CFG_ENV_SIZE		SZ_16K
+#define CONFIG_SKIP_LOWLEVEL_INIT	/* U-Boot is loaded by a bootloader */
+#define CONFIG_SKIP_RELOCATE_UBOOT	/* to a proper address, init done */
+#define CFG_NAND_BASE		0x02000000
+#define CFG_NAND_HW_ECC
+#define CFG_MAX_NAND_DEVICE	1	/* Max number of NAND devices */
+#define NAND_MAX_CHIPS		1
+#define CFG_ENV_OFFSET		0x0	/* Block 0--not used by bootcode */
+#define DEF_BOOTM		""
+#elif defined(CFG_USE_NOR)
+#ifdef CONFIG_NOR_UART_BOOT
+#define CONFIG_SKIP_LOWLEVEL_INIT	/* U-Boot is loaded by a bootloader */
+#define CONFIG_SKIP_RELOCATE_UBOOT	/* to a proper address, init done */
+#else
+#undef CONFIG_SKIP_LOWLEVEL_INIT
+#undef CONFIG_SKIP_RELOCATE_UBOOT
+#endif
+#define CFG_ENV_IS_IN_FLASH
+#undef CFG_NO_FLASH
+#define CFG_FLASH_CFI_DRIVER
+#define CFG_FLASH_CFI
+#define CFG_MAX_FLASH_BANKS	1		/* max number of flash banks */
+#define CFG_FLASH_SECT_SZ	0x20000		/* 128KB sect size AMD Flash */
+#define CFG_ENV_OFFSET		(CFG_FLASH_SECT_SZ*2)
+#define PHYS_FLASH_1		0x02000000	/* CS2 Base address 	 */
+#define CFG_FLASH_BASE		PHYS_FLASH_1	/* Flash Base for U-Boot */
+#define PHYS_FLASH_SIZE		0x2000000	/* Flash size 32MB 	 */
+#define CFG_MAX_FLASH_SECT	(PHYS_FLASH_SIZE/CFG_FLASH_SECT_SZ)
+#define CFG_ENV_SECT_SIZE	CFG_FLASH_SECT_SZ	/* Env sector Size */
+#endif
+/*==============================*/
+/* U-Boot general configuration */
+/*==============================*/
+#undef 	CONFIG_USE_IRQ			/* No IRQ/FIQ in U-Boot */
+#define CONFIG_MISC_INIT_R
+#undef CONFIG_BOOTDELAY
+#define CONFIG_BOOTFILE		"uImage"	/* Boot file name */
+#define CFG_PROMPT		"U-Boot > "	/* Monitor Command Prompt */
+#define CFG_CBSIZE		1024		/* Console I/O Buffer Size  */
+#define CFG_PBSIZE		(CFG_CBSIZE+sizeof(CFG_PROMPT)+16)	/* Print buffer sz */
+#define CFG_MAXARGS		16		/* max number of command args */
+#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR		0x80700000	/* default Linux kernel load address */
+#define CONFIG_VERSION_VARIABLE
+#define CONFIG_AUTO_COMPLETE		/* Won't work with hush so far, may be later */
+#define CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2	"> "
+#define CONFIG_CMDLINE_EDITING
+#define CFG_LONGHELP
+#define CONFIG_CRC32_VERIFY
+#define CONFIG_MX_CYCLIC
+/*===================*/
+/* Linux Information */
+/*===================*/
+#define LINUX_BOOT_PARAM_ADDR	0x80000100
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTARGS		"mem=56M console=ttyS0,115200n8 root=/dev/hda1 rw noinitrd ip=dhcp"
+#define CONFIG_BOOTCOMMAND	"setenv setboot setenv bootargs \\$(bootargs) video=dm64xxfb:output=\\$(videostd);run setboot; bootm 0x2060000"
+/*=================*/
+/* U-Boot commands */
+/*=================*/
+#include <config_cmd_default.h>
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_EEPROM
+#undef CONFIG_CMD_BDI
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_SETGETDCR
+#ifdef CFG_USE_NAND
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_IMLS
+#define CONFIG_CMD_NAND
+#elif defined(CFG_USE_NOR)
+#define CONFIG_CMD_JFFS2
+#else
+#error "Either CFG_USE_NAND or CFG_USE_NOR _MUST_ be defined !!!"
+#endif
+/*=======================*/
+/* KGDB support (if any) */
+/*=======================*/
+#ifdef CONFIG_CMD_KGDB
+#define CONFIG_KGDB_BAUDRATE	115200	/* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX	1	/* which serial port to use */
+#endif
+#endif /* __CONFIG_H */
diff --git a/include/configs/delta.h b/include/configs/delta.h
index dbfe7a702b54bc61b75da1375efa33be048c571b..09667edaa5a51754daed85157668d1d4c4d4b5cb 100644
--- a/include/configs/delta.h
+++ b/include/configs/delta.h
@@ -118,6 +118,18 @@
 
 #endif
 
+/* USB */
+#define CONFIG_USB_OHCI_NEW	1
+#define CONFIG_USB_STORAGE      1
+#define CONFIG_DOS_PARTITION    1
+
+#undef CFG_USB_OHCI_BOARD_INIT
+#define CFG_USB_OHCI_CPU_INIT	1
+#define CFG_USB_OHCI_REGS_BASE	OHCI_REGS_BASE
+#define CFG_USB_OHCI_SLOT_NAME	"delta"
+#define CFG_USB_OHCI_MAX_ROOT_PORTS	3
+
+#define LITTLEENDIAN            1       /* used by usb_ohci.c  */
 
 #define CONFIG_BOOTDELAY	-1
 #define CONFIG_ETHADDR		08:00:3e:26:0a:5b
diff --git a/include/configs/mp2usb.h b/include/configs/mp2usb.h
index 8d6f2613c17434cd87d2f22cd3a5681d8cba623a..ea5a44b1d1e0a8aec51f7893bba026125c396d22 100644
--- a/include/configs/mp2usb.h
+++ b/include/configs/mp2usb.h
@@ -101,12 +101,18 @@
 
 #undef	CONFIG_MODEM_SUPPORT		/* disable modem initialization stuff */
 
-#define CONFIG_USB_OHCI		1
+#define CONFIG_USB_OHCI_NEW	1
 #define CONFIG_USB_KEYBOARD	1
 #define CONFIG_USB_STORAGE	1
 #define CONFIG_DOS_PARTITION	1
 #define CONFIG_AT91C_PQFP_UHPBUG 1
 
+#undef CFG_USB_OHCI_BOARD_INIT
+#define CFG_USB_OHCI_CPU_INIT		1
+#define CFG_USB_OHCI_REGS_BASE		AT91_USB_HOST_BASE
+#define CFG_USB_OHCI_SLOT_NAME		"at91rm9200"
+#define CFG_USB_OHCI_MAX_ROOT_PORTS	15
+
 #undef CONFIG_HARD_I2C
 
 #ifdef CONFIG_HARD_I2C
@@ -123,7 +129,6 @@
 
 #define CONFIG_BOOTDELAY      3
 
-
 #if !defined(CONFIG_HARD_I2C)
 #define CONFIG_TIMESTAMP
 #endif
@@ -173,7 +178,7 @@
 
 #define CONFIG_NR_DRAM_BANKS	1
 #define PHYS_SDRAM		0x20000000
-#define PHYS_SDRAM_SIZE		0x08000000 	/* 128 megs */
+#define PHYS_SDRAM_SIZE		0x08000000	/* 128 megs */
 
 #define CFG_MEMTEST_START	PHYS_SDRAM
 #define CFG_MEMTEST_END		CFG_MEMTEST_START + PHYS_SDRAM_SIZE - 262144
diff --git a/include/configs/trab.h b/include/configs/trab.h
index 52bcbfc158b5895d0d80881f2b7a1c8fa5853696..dbccea28ad364dbde5e92ed0ad7fa5a5d02463ad 100644
--- a/include/configs/trab.h
+++ b/include/configs/trab.h
@@ -80,10 +80,17 @@
 #define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10
 
 /* USB stuff */
-#define CONFIG_USB_OHCI		1
+#define CONFIG_USB_OHCI_NEW	1
 #define CONFIG_USB_STORAGE	1
 #define CONFIG_DOS_PARTITION	1
 
+#undef CFG_USB_OHCI_BOARD_INIT
+#define CFG_USB_OHCI_CPU_INIT	1
+
+#define CFG_USB_OHCI_REGS_BASE	0x14200000
+#define CFG_USB_OHCI_SLOT_NAME	"s3c2400"
+#define CFG_USB_OHCI_MAX_ROOT_PORTS	15
+
 /*
  * Size of malloc() pool
  */
diff --git a/include/configs/yosemite.h b/include/configs/yosemite.h
index dd6d9acdd5de4163f8471289286d07e8fd60f9de..6a5b7f1eaacd4b38e07d22f56757e22a784c57e3 100644
--- a/include/configs/yosemite.h
+++ b/include/configs/yosemite.h
@@ -233,8 +233,15 @@
 
 #ifdef CONFIG_440EP
 /* USB */
-#define CONFIG_USB_OHCI
+#define CONFIG_USB_OHCI_NEW
 #define CONFIG_USB_STORAGE
+#define CFG_OHCI_BE_CONTROLLER
+
+#undef CFG_USB_OHCI_BOARD_INIT
+#define CFG_USB_OHCI_CPU_INIT	1
+#define CFG_USB_OHCI_REGS_BASE	(CFG_PERIPHERAL_BASE | 0x1000)
+#define CFG_USB_OHCI_SLOT_NAME	"ppc440"
+#define CFG_USB_OHCI_MAX_ROOT_PORTS	15
 
 /* Comment this out to enable USB 1.1 device */
 #define USB_2_0_DEVICE
diff --git a/include/da9030.h b/include/da9030.h
index 41108b9b36fbdec02b47faa436568345a55406a5..3e3b2024156d4a07518eaaea25c5f91a95182d23 100644
--- a/include/da9030.h
+++ b/include/da9030.h
@@ -104,3 +104,15 @@
 #define SYS_CONTROL_A_HWRES_ENABLE		(1<<2)
 #define SYS_CONTROL_A_WDOG_ACTION		(1<<3)
 #define SYS_CONTROL_A_WATCHDOG			(1<<7)
+
+#define MISC_CONTROLB_USB_INT_RISING		(1<<2)
+#define MISC_CONTROLB_SESSION_VALID_EN		(1<<3)
+
+#define USB_PUMP_USBVE				(1<<0)
+#define USB_PUMP_USBVEP				(1<<1)
+#define USB_PUMP_SRP_DETECT			(1<<2)
+#define USB_PUMP_SESSION_VALID			(1<<3)
+#define USB_PUMP_VBUS_VALID_4_0			(1<<4)
+#define USB_PUMP_VBUS_VALID_4_4			(1<<5)
+#define USB_PUMP_EN_USBVE			(1<<6)
+#define USB_PUMP_EN_USBVEP			(1<<7)
diff --git a/include/asm-avr32/div64.h b/include/div64.h
similarity index 100%
rename from include/asm-avr32/div64.h
rename to include/div64.h
diff --git a/include/dp83848.h b/include/dp83848.h
new file mode 100644
index 0000000000000000000000000000000000000000..274bc4c969c1eff8ac21b54b862e6aaea5f3c356
--- /dev/null
+++ b/include/dp83848.h
@@ -0,0 +1,88 @@
+/*
+ * DP83848 ethernet Physical layer
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ *
+ * 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.
+ */
+
+
+/* National Semiconductor PHYSICAL LAYER TRANSCEIVER DP83848 */
+
+#define DP83848_CTL_REG		0x0	/* Basic Mode Control Reg */
+#define DP83848_STAT_REG		0x1	/* Basic Mode Status Reg */
+#define DP83848_PHYID1_REG		0x2	/* PHY Idendifier Reg 1 */
+#define DP83848_PHYID2_REG		0x3	/* PHY Idendifier Reg 2 */
+#define DP83848_ANA_REG			0x4	/* Auto_Neg Advt Reg  */
+#define DP83848_ANLPA_REG		0x5	/* Auto_neg Link Partner Ability Reg */
+#define DP83848_ANE_REG			0x6	/* Auto-neg Expansion Reg  */
+#define DP83848_PHY_STAT_REG		0x10	/* PHY Status Register  */
+#define DP83848_PHY_INTR_CTRL_REG	0x11	/* PHY Interrupt Control Register */
+#define DP83848_PHY_CTRL_REG		0x19	/* PHY Status Register  */
+
+/*--Bit definitions: DP83848_CTL_REG */
+#define DP83848_RESET		(1 << 15)  /* 1= S/W Reset */
+#define DP83848_LOOPBACK	(1 << 14)  /* 1=loopback Enabled */
+#define DP83848_SPEED_SELECT	(1 << 13)
+#define DP83848_AUTONEG		(1 << 12)
+#define DP83848_POWER_DOWN	(1 << 11)
+#define DP83848_ISOLATE		(1 << 10)
+#define DP83848_RESTART_AUTONEG	(1 << 9)
+#define DP83848_DUPLEX_MODE	(1 << 8)
+#define DP83848_COLLISION_TEST	(1 << 7)
+
+/*--Bit definitions: DP83848_STAT_REG */
+#define DP83848_100BASE_T4	(1 << 15)
+#define DP83848_100BASE_TX_FD	(1 << 14)
+#define DP83848_100BASE_TX_HD	(1 << 13)
+#define DP83848_10BASE_T_FD	(1 << 12)
+#define DP83848_10BASE_T_HD	(1 << 11)
+#define DP83848_MF_PREAMB_SUPPR	(1 << 6)
+#define DP83848_AUTONEG_COMP	(1 << 5)
+#define DP83848_RMT_FAULT	(1 << 4)
+#define DP83848_AUTONEG_ABILITY	(1 << 3)
+#define DP83848_LINK_STATUS	(1 << 2)
+#define DP83848_JABBER_DETECT	(1 << 1)
+#define DP83848_EXTEND_CAPAB	(1 << 0)
+
+/*--definitions: DP83848_PHYID1 */
+#define DP83848_PHYID1_OUI	0x2000
+#define DP83848_PHYID2_OUI	0x5c90
+
+/*--Bit definitions: DP83848_ANAR, DP83848_ANLPAR */
+#define DP83848_NP		(1 << 15)
+#define DP83848_ACK		(1 << 14)
+#define DP83848_RF		(1 << 13)
+#define DP83848_PAUSE		(1 << 10)
+#define DP83848_T4		(1 << 9)
+#define DP83848_TX_FDX		(1 << 8)
+#define DP83848_TX_HDX		(1 << 7)
+#define DP83848_10_FDX		(1 << 6)
+#define DP83848_10_HDX		(1 << 5)
+#define DP83848_AN_IEEE_802_3	0x0001
+
+/*--Bit definitions: DP83848_ANER */
+#define DP83848_PDF		(1 << 4)
+#define DP83848_LP_NP_ABLE	(1 << 3)
+#define DP83848_NP_ABLE		(1 << 2)
+#define DP83848_PAGE_RX		(1 << 1)
+#define DP83848_LP_AN_ABLE	(1 << 0)
+
+/*--Bit definitions: DP83848_PHY_STAT */
+#define DP83848_RX_ERR_LATCH		(1 << 13)
+#define DP83848_POLARITY_STAT		(1 << 12)
+#define DP83848_FALSE_CAR_SENSE		(1 << 11)
+#define DP83848_SIG_DETECT		(1 << 10)
+#define DP83848_DESCRAM_LOCK		(1 << 9)
+#define DP83848_PAGE_RCV		(1 << 8)
+#define DP83848_PHY_RMT_FAULT		(1 << 6)
+#define DP83848_JABBER			(1 << 5)
+#define DP83848_AUTONEG_COMPLETE	(1 << 4)
+#define DP83848_LOOPBACK_STAT		(1 << 3)
+#define DP83848_DUPLEX			(1 << 2)
+#define DP83848_SPEED			(1 << 1)
+#define DP83848_LINK			(1 << 0)
diff --git a/include/exports.h b/include/exports.h
index 0516da93749be2c00d34ae575259b63eb9243a72..d6512cb3a45a1ed738ad9768d7a909469cb736cf 100644
--- a/include/exports.h
+++ b/include/exports.h
@@ -25,6 +25,9 @@ char *getenv (char *name);
 void setenv (char *varname, char *varvalue);
 long simple_strtol(const char *cp,char **endp,unsigned int base);
 int strcmp(const char * cs,const char * ct);
+#ifdef CONFIG_HAS_UID
+void forceenv (char *varname, char *varvalue);
+#endif
 #if defined(CONFIG_CMD_I2C)
 int i2c_write (uchar, uint, int , uchar* , int);
 int i2c_read (uchar, uint, int , uchar* , int);
diff --git a/include/mpc83xx.h b/include/mpc83xx.h
index 336c0ac4f22842720903988432fde9920fd5c2e9..829dbf93878109934df3a81dfe9ea3073b79d2af 100644
--- a/include/mpc83xx.h
+++ b/include/mpc83xx.h
@@ -86,6 +86,8 @@
 #define SPR_8360_REV12			0x80490012
 #define SPR_8360E_REV20			0x80480020
 #define SPR_8360_REV20			0x80490020
+#define SPR_8360E_REV21			0x80480021
+#define SPR_8360_REV21			0x80490021
 
 #define SPR_8323E_REV10			0x80620010
 #define SPR_8323_REV10			0x80630010
@@ -600,7 +602,9 @@
 #define SCCR_TSEC1CM_3			0xC0000000
 
 #define SCCR_TSEC1ON			0x20000000
+#define SCCR_TSEC1ON_SHIFT		29
 #define SCCR_TSEC2ON			0x10000000
+#define SCCR_TSEC2ON_SHIFT		28
 
 #endif
 
diff --git a/include/usb.h b/include/usb.h
index bf7155404170337c8b7e1701c1aca5582c761262..4e1539fa8820684b7c38e2cf00c283d7b6eeb07d 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -169,7 +169,10 @@ struct usb_device {
  * this is how the lowlevel part communicate with the outer world
  */
 
-#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined (CONFIG_USB_SL811HS)
+#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || \
+	defined(CONFIG_USB_OHCI_NEW) || defined (CONFIG_USB_SL811HS) || \
+	defined(CONFIG_USB_ISP116X_HCD)
+
 int usb_lowlevel_init(void);
 int usb_lowlevel_stop(void);
 int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len);
@@ -177,6 +180,7 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 			int transfer_len,struct devrequest *setup);
 int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 			int transfer_len, int interval);
+void usb_event_poll(void);
 
 /* Defines */
 #define USB_UHCI_VEND_ID 0x8086
@@ -230,16 +234,12 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
 
 /* big endian -> little endian conversion */
 /* some CPUs are already little endian e.g. the ARM920T */
-#ifdef LITTLEENDIAN
-#define swap_16(x) ((unsigned short)(x))
-#define swap_32(x) ((unsigned long)(x))
-#else
-#define swap_16(x) \
+#define __swap_16(x) \
 	({ unsigned short x_ = (unsigned short)x; \
 	 (unsigned short)( \
 		((x_ & 0x00FFU) << 8) | ((x_ & 0xFF00U) >> 8) ); \
 	})
-#define swap_32(x) \
+#define __swap_32(x) \
 	({ unsigned long x_ = (unsigned long)x; \
 	 (unsigned long)( \
 		((x_ & 0x000000FFUL) << 24) | \
@@ -247,6 +247,13 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
 		((x_ & 0x00FF0000UL) >>	 8) | \
 		((x_ & 0xFF000000UL) >> 24) ); \
 	})
+
+#ifdef LITTLEENDIAN
+# define swap_16(x) (x)
+# define swap_32(x) (x)
+#else
+# define swap_16(x) __swap_16(x)
+# define swap_32(x) __swap_32(x)
 #endif /* LITTLEENDIAN */
 
 /*
diff --git a/include/usb_cdc_acm.h b/include/usb_cdc_acm.h
new file mode 100644
index 0000000000000000000000000000000000000000..87bf50c52baced5f450fb56f0ea2680981ed0367
--- /dev/null
+++ b/include/usb_cdc_acm.h
@@ -0,0 +1,43 @@
+/*
+ * (C) Copyright 2006
+ * Bryan O'Donoghue, deckard@codehermit.ie, CodeHermit
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/* ACM Control Requests */
+#define ACM_SEND_ENCAPSULATED_COMMAND	0x00
+#define ACM_GET_ENCAPSULATED_RESPONSE	0x01
+#define ACM_SET_COMM_FEATURE		0x02
+#define ACM_GET_COMM_FEATRUE		0x03
+#define ACM_CLEAR_COMM_FEATURE		0x04
+#define ACM_SET_LINE_ENCODING		0x20
+#define ACM_GET_LINE_ENCODING		0x21
+#define ACM_SET_CONTROL_LINE_STATE	0x22
+#define ACM_SEND_BREAK			0x23
+
+/* ACM Notification Codes */
+#define ACM_NETWORK_CONNECTION		0x00
+#define ACM_RESPONSE_AVAILABLE		0x01
+#define ACM_SERIAL_STATE		0x20
+
+/* Format of response expected by a ACM_GET_LINE_ENCODING request */
+struct rs232_emu{
+		unsigned long dter;
+		unsigned char stop_bits;
+		unsigned char parity;
+		unsigned char data_bits;
+}__attribute__((packed));
diff --git a/include/usbdcore.h b/include/usbdcore.h
index 6e92df13bd0edfe8f76e02c4c9e8776831869f68..cb2be72804a4f1ca6b3b83e2b63395353f61a6d0 100644
--- a/include/usbdcore.h
+++ b/include/usbdcore.h
@@ -576,6 +576,9 @@ struct usb_device_instance {
 
 	void (*event) (struct usb_device_instance *device, usb_device_event_t event, int data);
 
+	/* Do cdc device specific control requests */
+	int (*cdc_recv_setup)(struct usb_device_request *request, struct urb *urb);
+
 	/* bus interface */
 	struct usb_bus_instance *bus;	/* which bus interface driver */
 
diff --git a/include/usbdcore_mpc8xx.h b/include/usbdcore_mpc8xx.h
new file mode 100644
index 0000000000000000000000000000000000000000..9df62f4ca5130453759e944e024b08e7203faf84
--- /dev/null
+++ b/include/usbdcore_mpc8xx.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2006 Bryan O'Donoghue, CodeHermit
+ * bodonoghue@codehermit.ie
+ *
+ *
+ * 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 <commproc.h>
+
+/* Mode Register */
+#define USMOD_EN	0x01
+#define USMOD_HOST	0x02
+#define USMOD_TEST	0x04
+#define USMOD_SFTE	0x08
+#define USMOD_RESUME	0x40
+#define USMOD_LSS	0x80
+
+/* Endpoint Registers */
+#define USEP_RHS_NORM	0x00
+#define USEP_RHS_IGNORE	0x01
+#define USEP_RHS_NAK	0x02
+#define USEP_RHS_STALL	0x03
+
+#define USEP_THS_NORM	0x00
+#define USEP_THS_IGNORE	0x04
+#define USEP_THS_NAK	0x08
+#define USEP_THS_STALL	0x0C
+
+#define USEP_RTE	0x10
+#define USEP_MF		0x20
+
+#define USEP_TM_CONTROL	0x00
+#define USEP_TM_INT	0x100
+#define USEP_TM_BULK	0x200
+#define USEP_TM_ISO	0x300
+
+/* Command Register */
+#define USCOM_EP0	0x00
+#define USCOM_EP1	0x01
+#define USCOM_EP2	0x02
+#define USCOM_EP3	0x03
+
+#define USCOM_FLUSH	0x40
+#define USCOM_STR	0x80
+
+/* Event Register */
+#define USB_E_RXB	0x0001
+#define USB_E_TXB	0x0002
+#define USB_E_BSY	0x0004
+#define USB_E_SOF	0x0008
+#define USB_E_TXE1	0x0010
+#define USB_E_TXE2	0x0020
+#define USB_E_TXE3	0x0040
+#define USB_E_TXE4	0x0080
+#define USB_TX_ERRMASK (USB_E_TXE1|USB_E_TXE2|USB_E_TXE3|USB_E_TXE4)
+#define USB_E_IDLE	0x0100
+#define USB_E_RESET	0x0200
+
+/* Mask Register */
+#define USBS_IDLE	0x01
+
+/* RX Buffer Descriptor */
+#define RX_BD_OV	0x02
+#define RX_BD_CR	0x04
+#define RX_BD_AB	0x08
+#define RX_BD_NO	0x10
+#define RX_BD_PID_DATA0	0x00
+#define RX_BD_PID_DATA1	0x40
+#define RX_BD_PID_SETUP	0x80
+#define RX_BD_F		0x400
+#define RX_BD_L		0x800
+#define RX_BD_I		0x1000
+#define RX_BD_W		0x2000
+#define RX_BD_E		0x8000
+
+/* Useful masks */
+#define RX_BD_PID_BITMASK (RX_BD_PID_DATA1 | RX_BD_PID_SETUP)
+#define STALL_BITMASK (USEP_THS_STALL | USEP_RHS_STALL)
+#define NAK_BITMASK (USEP_THS_NAK | USEP_RHS_NAK)
+#define CBD_TX_BITMASK (TX_BD_R | TX_BD_L | TX_BD_TC | TX_BD_I | TX_BD_CNF)
+
+/* TX Buffer Descriptor */
+#define TX_BD_UN	0x02
+#define TX_BD_TO	0x04
+#define TX_BD_NO_PID	0x00
+#define TX_BD_PID_DATA0	0x80
+#define TX_BD_PID_DATA1	0xC0
+#define TX_BD_CNF	0x200
+#define TX_BD_TC	0x400
+#define TX_BD_L		0x800
+#define TX_BD_I		0x1000
+#define TX_BD_W		0x2000
+#define TX_BD_R		0x8000
+
+/* Implementation specific defines */
+
+#define EP_MIN_PACKET_SIZE 0x08
+#define MAX_ENDPOINTS	0x04
+#define FIFO_SIZE	0x10
+#define EP_MAX_PKT	FIFO_SIZE
+#define TX_RING_SIZE	0x04
+#define RX_RING_SIZE	0x06
+#define USB_MAX_PKT	0x40
+#define TOGGLE_TX_PID(x) x= ((~x)&0x40)|0x80
+#define TOGGLE_RX_PID(x) x^= 0x40
+#define EP_ATTACHED	0x01	/* Endpoint has a urb attached or not */
+#define EP_SEND_ZLP	0x02	/* Send ZLP y/n ? */
+
+#define PROFF_USB	0x00000000
+#define CPM_USB_BASE	0x00000A00
+
+/* UDC device defines */
+#define EP0_MAX_PACKET_SIZE	EP_MAX_PKT
+#define UDC_OUT_ENDPOINT	0x02
+#define UDC_OUT_PACKET_SIZE	EP_MIN_PACKET_SIZE
+#define UDC_IN_ENDPOINT		0x03
+#define UDC_IN_PACKET_SIZE	EP_MIN_PACKET_SIZE
+#define UDC_INT_ENDPOINT	0x01
+#define UDC_INT_PACKET_SIZE	UDC_IN_PACKET_SIZE
+#define UDC_BULK_PACKET_SIZE	EP_MIN_PACKET_SIZE
+
+struct mpc8xx_ep {
+	struct urb * urb;
+	unsigned char pid;
+	unsigned char sc;
+	volatile cbd_t * prx;
+};
+
+typedef struct mpc8xx_usb{
+	char usmod;	/* Mode Register */
+	char usaddr;	/* Slave Address Register */
+	char uscom;	/* Command Register */
+	char res1;	/* Reserved */
+	ushort usep[4];
+	ulong res2;	/* Reserved */
+	ushort usber;	/* Event Register */
+	ushort res3;	/* Reserved */
+	ushort usbmr;	/* Mask Register */
+	char res4;	/* Reserved */
+	char usbs;	/* Status Register */
+	char res5[8];	/* Reserved */
+}usb_t;
+
+typedef struct mpc8xx_parameter_ram{
+	ushort ep0ptr;	/* Endpoint Pointer Register 0 */
+	ushort ep1ptr;	/* Endpoint Pointer Register 1 */
+	ushort ep2ptr;	/* Endpoint Pointer Register 2 */
+	ushort ep3ptr;	/* Endpoint Pointer Register 3 */
+	uint rstate;	/* Receive state */
+	uint rptr;	/* Receive internal data pointer */
+	ushort frame_n;	/* Frame number */
+	ushort rbcnt;	/* Receive byte count */
+	uint rtemp;	/* Receive temp cp use only */
+	uint rxusb;	/* Rx Data Temp */
+	ushort rxuptr;	/* Rx microcode return address temp */
+}usb_pram_t;
+
+typedef struct endpoint_parameter_block_pointer{
+	ushort rbase;	/* RxBD base address */
+	ushort tbase;	/* TxBD base address */
+	char rfcr;	/* Rx Function code */
+	char tfcr;	/* Tx Function code */
+	ushort mrblr;	/* Maximum Receive Buffer Length */
+	ushort rbptr; 	/* RxBD pointer Next Buffer Descriptor */
+	ushort tbptr;	/* TxBD pointer Next Buffer Descriptor  */
+	ulong tstate;	/* Transmit internal state */
+	ulong tptr;	/* Transmit internal data pointer */
+	ushort tcrc;	/* Transmit temp CRC */
+	ushort tbcnt;	/* Transmit internal bye count */
+	ulong ttemp;	/* Tx temp */
+	ushort txuptr;	/* Tx microcode return address */
+	ushort res1;	/* Reserved */
+}usb_epb_t;
+
+typedef enum mpc8xx_udc_state{
+	STATE_NOT_READY,
+	STATE_ERROR,
+	STATE_READY,
+}mpc8xx_udc_state_t;
+
+/* Declarations */
+int udc_init(void);
+void udc_irq(void);
+int udc_endpoint_write(struct usb_endpoint_instance *endpoint);
+void udc_setup_ep(struct usb_device_instance *device, unsigned int ep,
+		  struct usb_endpoint_instance *endpoint);
+void udc_connect(void);
+void udc_disconnect(void);
+void udc_enable(struct usb_device_instance *device);
+void udc_disable(void);
+void udc_startup_events(struct usb_device_instance *device);
+
+/* Flow control */
+void udc_set_nak(int epid);
+void udc_unset_nak (int epid);
diff --git a/include/usbdcore_omap1510.h b/include/usbdcore_omap1510.h
index 6ea333122fde66e314d383156df513931032381b..526fcd920db32fc1f8f6d1d77cbc0755462ec09c 100644
--- a/include/usbdcore_omap1510.h
+++ b/include/usbdcore_omap1510.h
@@ -161,10 +161,20 @@
 #define UDC_VBUS_CTRL	    (1 << 19)
 #define UDC_VBUS_MODE	    (1 << 18)
 
-
-void omap1510_udc_irq(void);
-void omap1510_udc_noniso_irq(void);
-
+/* OMAP Endpoint parameters */
+#define EP0_MAX_PACKET_SIZE 64
+#define UDC_OUT_ENDPOINT 2
+#define UDC_OUT_PACKET_SIZE 64
+#define UDC_IN_ENDPOINT	1
+#define UDC_IN_PACKET_SIZE 64
+#define UDC_INT_ENDPOINT 5
+#define UDC_INT_PKTSIZE	16
+#define UDC_BULK_PKTSIZE 16
+
+void udc_irq (void);
+/* Flow control */
+void udc_set_nak(int epid);
+void udc_unset_nak (int epid);
 
 /* Higher level functions for abstracting away from specific device */
 void udc_endpoint_write(struct usb_endpoint_instance *endpoint);
diff --git a/include/usbdescriptors.h b/include/usbdescriptors.h
index 2d9f739343e23176c77608d56c4090198781a8c3..a752097e5bcc6cdc1aef7ef6521ea2591196680b 100644
--- a/include/usbdescriptors.h
+++ b/include/usbdescriptors.h
@@ -92,33 +92,42 @@
 #define COMMUNICATIONS_DEVICE_CLASS	0x02
 
 /* c.f. CDC 4.2 Table 15 */
-#define COMMUNICATIONS_INTERFACE_CLASS	0x02
+#define COMMUNICATIONS_INTERFACE_CLASS_CONTROL	0x02
+#define COMMUNICATIONS_INTERFACE_CLASS_DATA		0x0A
+#define COMMUNICATIONS_INTERFACE_CLASS_VENDOR	0x0FF
 
 /* c.f. CDC 4.3 Table 16 */
-#define COMMUNICATIONS_NO_SUBCLASS	0x00
+#define COMMUNICATIONS_NO_SUBCLASS		0x00
 #define COMMUNICATIONS_DLCM_SUBCLASS	0x01
-#define COMMUNICATIONS_ACM_SUBCLASS	0x02
-#define COMMUNICATIONS_TCM_SUBCLASS	0x03
+#define COMMUNICATIONS_ACM_SUBCLASS		0x02
+#define COMMUNICATIONS_TCM_SUBCLASS		0x03
 #define COMMUNICATIONS_MCCM_SUBCLASS	0x04
-#define COMMUNICATIONS_CCM_SUBCLASS	0x05
+#define COMMUNICATIONS_CCM_SUBCLASS		0x05
 #define COMMUNICATIONS_ENCM_SUBCLASS	0x06
 #define COMMUNICATIONS_ANCM_SUBCLASS	0x07
 
 /* c.f. WMCD 5.1 */
 #define COMMUNICATIONS_WHCM_SUBCLASS	0x08
-#define COMMUNICATIONS_DMM_SUBCLASS	0x09
+#define COMMUNICATIONS_DMM_SUBCLASS		0x09
 #define COMMUNICATIONS_MDLM_SUBCLASS	0x0a
 #define COMMUNICATIONS_OBEX_SUBCLASS	0x0b
 
-/* c.f. CDC 4.6 Table 18 */
+/* c.f. CDC 4.4 Table 17 */
+#define COMMUNICATIONS_NO_PROTOCOL		0x00
+#define COMMUNICATIONS_V25TER_PROTOCOL	0x01	/*Common AT Hayes compatible*/
+
+/* c.f. CDC 4.5 Table 18 */
 #define DATA_INTERFACE_CLASS		0x0a
 
+/* c.f. CDC 4.6 No Table */
+#define DATA_INTERFACE_SUBCLASS_NONE	0x00	/* No subclass pertinent */
+
 /* c.f. CDC 4.7 Table 19 */
-#define COMMUNICATIONS_NO_PROTOCOL	0x00
+#define DATA_INTERFACE_PROTOCOL_NONE	0x00	/* No class protcol required */
 
 
 /* c.f. CDC 5.2.3 Table 24 */
-#define CS_INTERFACE			0x24
+#define CS_INTERFACE		0x24
 #define CS_ENDPOINT			0x25
 
 /*
@@ -128,7 +137,7 @@
  * c.f. WMCD 5.3 Table 5.3
  */
 
-#define USB_ST_HEADER			0x00
+#define USB_ST_HEADER		0x00
 #define USB_ST_CMF			0x01
 #define USB_ST_ACMF			0x02
 #define USB_ST_DLMF			0x03
@@ -137,18 +146,18 @@
 #define USB_ST_UF			0x06
 #define USB_ST_CSF			0x07
 #define USB_ST_TOMF			0x08
-#define USB_ST_USBTF			0x09
+#define USB_ST_USBTF		0x09
 #define USB_ST_NCT			0x0a
 #define USB_ST_PUF			0x0b
 #define USB_ST_EUF			0x0c
 #define USB_ST_MCMF			0x0d
 #define USB_ST_CCMF			0x0e
 #define USB_ST_ENF			0x0f
-#define USB_ST_ATMNF			0x10
+#define USB_ST_ATMNF		0x10
 
 #define USB_ST_WHCM			0x11
 #define USB_ST_MDLM			0x12
-#define USB_ST_MDLMD			0x13
+#define USB_ST_MDLMD		0x13
 #define USB_ST_DMM			0x14
 #define USB_ST_OBEX			0x15
 #define USB_ST_CS			0x16
@@ -312,7 +321,8 @@ struct usb_class_union_function_descriptor {
 	u8 bDescriptorType;
 	u8 bDescriptorSubtype;	/* 0x06 */
 	u8 bMasterInterface;
-	u8 bSlaveInterface0[0];
+	/* u8 bSlaveInterface0[0]; */
+	u8 bSlaveInterface0;
 } __attribute__ ((packed));
 
 struct usb_class_country_selection_descriptor {
diff --git a/lib_arm/board.c b/lib_arm/board.c
index 8f4e19bfcb5bf637452cc944d90a5ae58a965c41..d37e5dab3524839af18a05ed920ce804537d0efb 100644
--- a/lib_arm/board.c
+++ b/lib_arm/board.c
@@ -364,6 +364,13 @@ void start_armboot (void)
 	enable_interrupts ();
 
 	/* Perform network card initialisation if necessary */
+#ifdef CONFIG_DRIVER_TI_EMAC
+extern void dm644x_eth_set_mac_addr (const u_int8_t *addr);
+	if (getenv ("ethaddr")) {
+		dm644x_eth_set_mac_addr(gd->bd->bi_enetaddr);
+	}
+#endif
+
 #ifdef CONFIG_DRIVER_CS8900
 	cs8900_get_enetaddr (gd->bd->bi_enetaddr);
 #endif
diff --git a/lib_avr32/Makefile b/lib_avr32/Makefile
index cf20836023fd4f8967e6a5bf019e971c008e192e..bb2938fe5c2206102477e45282d0d989a6ad4610 100644
--- a/lib_avr32/Makefile
+++ b/lib_avr32/Makefile
@@ -29,7 +29,7 @@ LIB	= $(obj)lib$(ARCH).a
 
 SOBJS	= memset.o
 
-COBJS	= board.o interrupts.o avr32_linux.o div64.o
+COBJS	= board.o interrupts.o avr32_linux.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/lib_generic/Makefile b/lib_generic/Makefile
index b2091c5e78bd6cc1b8f98dc6bae719bc82f58c01..bf377529c20a802b02a0cf9db27e54bf1584d0f1 100644
--- a/lib_generic/Makefile
+++ b/lib_generic/Makefile
@@ -27,7 +27,7 @@ LIB	= $(obj)libgeneric.a
 
 COBJS	= bzlib.o bzlib_crctable.o bzlib_decompress.o \
 	  bzlib_randtable.o bzlib_huffman.o \
-	  crc32.o ctype.o display_options.o ldiv.o sha1.o \
+	  crc32.o ctype.o display_options.o div64.o ldiv.o sha1.o \
 	  string.o vsprintf.o zlib.o
 
 SRCS 	:= $(COBJS:.o=.c)
diff --git a/lib_avr32/div64.c b/lib_generic/div64.c
similarity index 97%
rename from lib_avr32/div64.c
rename to lib_generic/div64.c
index 99726e325dafc263ddaf23bd7190e67420442df2..d9951b597f9fd4a798be978d48794b6c9fd8205e 100644
--- a/lib_avr32/div64.c
+++ b/lib_generic/div64.c
@@ -18,8 +18,6 @@
 
 #include <linux/types.h>
 
-#include <asm/div64.h>
-
 uint32_t __div64_32(uint64_t *n, uint32_t base)
 {
 	uint64_t rem = *n;
diff --git a/lib_ppc/board.c b/lib_ppc/board.c
index 325f5c219ced78f352f04b13d13ec30fb820dd3b..c87d46c3d626a1b00bb06fc373aaf6f1dcc24001 100644
--- a/lib_ppc/board.c
+++ b/lib_ppc/board.c
@@ -309,7 +309,9 @@ init_fnc_t *init_sequence[] = {
 	prt_8260_rsr,
 	prt_8260_clks,
 #endif /* CONFIG_8260 */
-
+#if defined(CONFIG_MPC83XX)
+	prt_83xx_rsr,
+#endif
 	checkcpu,
 #if defined(CONFIG_MPC5xxx)
 	prt_mpc5xxx_clks,
@@ -376,7 +378,7 @@ void board_init_f (ulong bootflag)
 	/* compiler optimization barrier needed for GCC >= 3.4 */
 	__asm__ __volatile__("": : :"memory");
 
-#if !defined(CONFIG_CPM2)
+#if !defined(CONFIG_CPM2) && !defined(CONFIG_MPC83XX)
 	/* Clear initial global data */
 	memset ((void *) gd, 0, sizeof (gd_t));
 #endif
diff --git a/net/eth.c b/net/eth.c
index 6576ee405bb19a065a920b8db043d35ee113a8be..c8f92a526342ed90eca7b9c98dded00fc4c8b90f 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -464,6 +464,8 @@ extern int at91rm9200_miiphy_initialize(bd_t *bis);
 extern int emac4xx_miiphy_initialize(bd_t *bis);
 extern int mcf52x2_miiphy_initialize(bd_t *bis);
 extern int ns7520_miiphy_initialize(bd_t *bis);
+extern int dm644x_eth_miiphy_initialize(bd_t *bis);
+
 
 int eth_initialize(bd_t *bis)
 {
@@ -483,6 +485,9 @@ int eth_initialize(bd_t *bis)
 #endif
 #if defined(CONFIG_NETARM)
 	ns7520_miiphy_initialize(bis);
+#endif
+#if defined(CONFIG_DRIVER_TI_EMAC)
+	dm644x_eth_miiphy_initialize(bis);
 #endif
 	return 0;
 }