Merge branch 'master' of git://git.denx.de/u-boot-microblaze

* 'master' of git://git.denx.de/u-boot-microblaze:
  microblaze: Wire up SPI driver
  spi: microblaze: Adds driver for Xilinx SPI controller
  microblaze: intc: Clear interrupt code
  microblaze: Call serial multi initialization
  microblaze: Move __udelay implementation
  microblaze: Remove extern from board.c
  microblaze: Wire up dts configuration
  fdt: Add board specific dts inclusion
  microblaze: Move individual board linker scripts to common script in cpu tree.
  microblaze: Add gpio.h
  microblaze: Add missing undefs for UBI and UBIFS
  microblaze: Expand and correct configuration comments
  microblaze: Enable ubi support
  microblaze: Avoid compile error on systems without cfi flash
  microblaze: Remove wrong define CONFIG_SYS_FLASH_PROTECTION

Conflicts:
	drivers/spi/Makefile

Signed-off-by: Wolfgang Denk <wd@denx.de>
diff --git a/arch/microblaze/config.mk b/arch/microblaze/config.mk
index abea70b..aca79e2 100644
--- a/arch/microblaze/config.mk
+++ b/arch/microblaze/config.mk
@@ -29,3 +29,5 @@
 CONFIG_STANDALONE_LOAD_ADDR ?= 0x80F00000
 
 PLATFORM_CPPFLAGS += -ffixed-r31 -D__microblaze__
+
+LDSCRIPT ?= $(SRCTREE)/$(CPUDIR)/u-boot.lds
diff --git a/arch/microblaze/cpu/interrupts.c b/arch/microblaze/cpu/interrupts.c
index e7ca859..ee67082 100644
--- a/arch/microblaze/cpu/interrupts.c
+++ b/arch/microblaze/cpu/interrupts.c
@@ -26,6 +26,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <malloc.h>
 #include <asm/microblaze_intc.h>
 #include <asm/asm.h>
 
@@ -48,20 +49,19 @@
 	return (msr & 0x2) != 0;
 }
 
-#ifdef CONFIG_SYS_INTC_0
-
-static struct irq_action vecs[CONFIG_SYS_INTC_0_NUM];
+static struct irq_action *vecs;
+static u32 irq_no;
 
 /* mapping structure to interrupt controller */
-microblaze_intc_t *intc = (microblaze_intc_t *) (CONFIG_SYS_INTC_0_ADDR);
+microblaze_intc_t *intc;
 
 /* default handler */
-void def_hdlr (void)
+static void def_hdlr(void)
 {
 	puts ("def_hdlr\n");
 }
 
-void enable_one_interrupt (int irq)
+static void enable_one_interrupt(int irq)
 {
 	int mask;
 	int offset = 1;
@@ -76,7 +76,7 @@
 #endif
 }
 
-void disable_one_interrupt (int irq)
+static void disable_one_interrupt(int irq)
 {
 	int mask;
 	int offset = 1;
@@ -96,7 +96,7 @@
 {
 	struct irq_action *act;
 	/* irq out of range */
-	if ((irq < 0) || (irq > CONFIG_SYS_INTC_0_NUM)) {
+	if ((irq < 0) || (irq > irq_no)) {
 		puts ("IRQ out of range\n");
 		return;
 	}
@@ -114,7 +114,7 @@
 }
 
 /* initialization interrupt controller - hardware */
-void intc_init (void)
+static void intc_init(void)
 {
 	intc->mer = 0;
 	intc->ier = 0;
@@ -127,18 +127,33 @@
 #endif
 }
 
-int interrupts_init (void)
+int interrupts_init(void)
 {
 	int i;
-	/* initialize irq list */
-	for (i = 0; i < CONFIG_SYS_INTC_0_NUM; i++) {
-		vecs[i].handler = (interrupt_handler_t *) def_hdlr;
-		vecs[i].arg = (void *)i;
-		vecs[i].count = 0;
+
+#if defined(CONFIG_SYS_INTC_0_ADDR) && defined(CONFIG_SYS_INTC_0_NUM)
+	intc = (microblaze_intc_t *) (CONFIG_SYS_INTC_0_ADDR);
+	irq_no = CONFIG_SYS_INTC_0_NUM;
+#endif
+	if (irq_no) {
+		vecs = calloc(1, sizeof(struct irq_action) * irq_no);
+		if (vecs == NULL) {
+			puts("Interrupt vector allocation failed\n");
+			return -1;
+		}
+
+		/* initialize irq list */
+		for (i = 0; i < irq_no; i++) {
+			vecs[i].handler = (interrupt_handler_t *) def_hdlr;
+			vecs[i].arg = (void *)i;
+			vecs[i].count = 0;
+		}
+		/* initialize intc controller */
+		intc_init();
+		enable_interrupts();
+	} else {
+		puts("Undefined interrupt controller\n");
 	}
-	/* initialize intc controller */
-	intc_init ();
-	enable_interrupts ();
 	return 0;
 }
 
@@ -172,33 +187,30 @@
 	printf ("Interrupt handler on %x line, r14 %x\n", irqs, value);
 #endif
 }
-#endif
 
 #if defined(CONFIG_CMD_IRQ)
-#ifdef CONFIG_SYS_INTC_0
-int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, const char *argv[])
 {
 	int i;
 	struct irq_action *act = vecs;
 
-	puts ("\nInterrupt-Information:\n\n"
-	      "Nr  Routine   Arg       Count\n"
-	      "-----------------------------\n");
+	if (irq_no) {
+		puts("\nInterrupt-Information:\n\n"
+		      "Nr  Routine   Arg       Count\n"
+		      "-----------------------------\n");
 
-	for (i = 0; i < CONFIG_SYS_INTC_0_NUM; i++) {
-		if (act->handler != (interrupt_handler_t*) def_hdlr) {
-			printf ("%02d  %08x  %08x  %d\n", i,
-				(int)act->handler, (int)act->arg, act->count);
+		for (i = 0; i < irq_no; i++) {
+			if (act->handler != (interrupt_handler_t *) def_hdlr) {
+				printf("%02d  %08x  %08x  %d\n", i,
+					(int)act->handler, (int)act->arg,
+								act->count);
+			}
+			act++;
 		}
-		act++;
+		puts("\n");
+	} else {
+		puts("Undefined interrupt controller\n");
 	}
-	puts ("\n");
-	return (0);
+	return 0;
 }
-#else
-int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
-{
-	puts ("Undefined interrupt controller\n");
-}
-#endif
 #endif
diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S
index 9077f74..8a2f634 100644
--- a/arch/microblaze/cpu/start.S
+++ b/arch/microblaze/cpu/start.S
@@ -108,7 +108,6 @@
 	sh	r6, r0, r8
 #endif
 
-#ifdef CONFIG_SYS_INTC_0
 	/* interrupt_handler */
 	swi	r2, r0, 0x10	/* interrupt - imm opcode */
 	swi	r3, r0, 0x14	/* interrupt - brai opcode */
@@ -120,7 +119,6 @@
 	sh	r7, r0, r8
 	rsubi	r8, r10, 0x16
 	sh	r6, r0, r8
-#endif
 
 	/* hardware exception */
 	swi	r2, r0, 0x20	/* hardware exception - imm opcode */
diff --git a/arch/microblaze/cpu/timer.c b/arch/microblaze/cpu/timer.c
index 1952804..cc6b897 100644
--- a/arch/microblaze/cpu/timer.c
+++ b/arch/microblaze/cpu/timer.c
@@ -40,7 +40,25 @@
 }
 #endif
 
-#ifdef CONFIG_SYS_INTC_0
+#ifdef CONFIG_SYS_TIMER_0
+void __udelay(unsigned long usec)
+{
+	int i;
+
+	i = get_timer(0);
+	while ((get_timer(0) - i) < (usec / 1000))
+		;
+}
+#else
+void __udelay(unsigned long usec)
+{
+	unsigned int i;
+
+	for (i = 0; i < (usec * CONFIG_XILINX_CLOCK_FREQ / 10000000); i++)
+		;
+}
+#endif
+
 #ifdef CONFIG_SYS_TIMER_0
 microblaze_timer_t *tmr = (microblaze_timer_t *) (CONFIG_SYS_TIMER_0_ADDR);
 
@@ -61,7 +79,6 @@
 	return 0;
 }
 #endif
-#endif
 
 /*
  * This function is derived from PowerPC code (read timebase as long long).
diff --git a/board/xilinx/microblaze-generic/u-boot.lds b/arch/microblaze/cpu/u-boot.lds
similarity index 100%
rename from board/xilinx/microblaze-generic/u-boot.lds
rename to arch/microblaze/cpu/u-boot.lds
diff --git a/arch/microblaze/include/asm/gpio.h b/arch/microblaze/include/asm/gpio.h
new file mode 100644
index 0000000..883f4d4
--- /dev/null
+++ b/arch/microblaze/include/asm/gpio.h
@@ -0,0 +1,41 @@
+#ifndef _ASM_MICROBLAZE_GPIO_H_
+#define _ASM_MICROBLAZE_GPIO_H_
+
+#include <asm/io.h>
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+	return 0;
+}
+
+static inline int gpio_free(unsigned gpio)
+{
+	return 0;
+}
+
+static inline int gpio_direction_input(unsigned gpio)
+{
+	return 0;
+}
+
+static inline int gpio_direction_output(unsigned gpio, int value)
+{
+	return 0;
+}
+
+static inline int gpio_get_value(unsigned gpio)
+{
+	return 0;
+}
+
+static inline int gpio_set_value(unsigned gpio, int value)
+{
+	return 0;
+}
+
+static inline int gpio_is_valid(int number)
+{
+	return 0;
+}
+#endif
+
diff --git a/arch/microblaze/include/asm/microblaze_intc.h b/arch/microblaze/include/asm/microblaze_intc.h
index 4c385aa..6142b9c 100644
--- a/arch/microblaze/include/asm/microblaze_intc.h
+++ b/arch/microblaze/include/asm/microblaze_intc.h
@@ -41,3 +41,6 @@
 
 void install_interrupt_handler (int irq, interrupt_handler_t * hdlr,
 				       void *arg);
+
+int interrupts_init(void);
+
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile
index de0a7d3..7730695 100644
--- a/arch/microblaze/lib/Makefile
+++ b/arch/microblaze/lib/Makefile
@@ -29,7 +29,6 @@
 
 COBJS-y	+= board.o
 COBJS-y	+= bootm.o
-COBJS-y	+= time.o
 
 SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c
index f3679d5..b80250a 100644
--- a/arch/microblaze/lib/board.c
+++ b/arch/microblaze/lib/board.c
@@ -30,21 +30,16 @@
 #include <version.h>
 #include <watchdog.h>
 #include <stdio_dev.h>
+#include <serial.h>
 #include <net.h>
 #include <asm/processor.h>
+#include <asm/microblaze_intc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef CONFIG_SYS_GPIO_0
 extern int gpio_init (void);
 #endif
-#ifdef CONFIG_SYS_INTC_0
-extern int interrupts_init (void);
-#endif
-
-#if defined(CONFIG_CMD_NET)
-extern int eth_init (bd_t * bis);
-#endif
 #ifdef CONFIG_SYS_TIMER_0
 extern int timer_init (void);
 #endif
@@ -73,9 +68,7 @@
 #ifdef CONFIG_SYS_GPIO_0
 	gpio_init,
 #endif
-#ifdef CONFIG_SYS_INTC_0
 	interrupts_init,
-#endif
 #ifdef CONFIG_SYS_TIMER_0
 	timer_init,
 #endif
@@ -117,6 +110,10 @@
 	 */
 	mem_malloc_init (CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
 
+#ifdef CONFIG_SERIAL_MULTI
+	serial_initialize();
+#endif
+
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		WATCHDOG_RESET ();
 		if ((*init_fnc_ptr) () != 0) {
diff --git a/arch/microblaze/lib/time.c b/arch/microblaze/lib/time.c
index da016a0..e69de29 100644
--- a/arch/microblaze/lib/time.c
+++ b/arch/microblaze/lib/time.c
@@ -1,42 +0,0 @@
-/*
- * (C) Copyright 2007 Michal Simek
- * (C) Copyright 2004 Atmark Techno, Inc.
- *
- * Michal  SIMEK <monstr@monstr.eu>
- * Yasushi SHOJI <yashi@atmark-techno.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.
- *
- * 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_SYS_TIMER_0
-void __udelay (unsigned long usec)
-{
-	int i;
-	i = get_timer (0);
-	while ((get_timer (0) - i) < (usec / 1000)) ;
-}
-#else
-void __udelay (unsigned long usec)
-{
-	unsigned int i;
-	for (i = 0; i < (usec * CONFIG_XILINX_CLOCK_FREQ / 10000000); i++);
-}
-#endif
diff --git a/board/xilinx/dts/microblaze.dts b/board/xilinx/dts/microblaze.dts
new file mode 100644
index 0000000..bf984b0
--- /dev/null
+++ b/board/xilinx/dts/microblaze.dts
@@ -0,0 +1 @@
+/include/ BOARD_DTS
diff --git a/board/xilinx/microblaze-generic/dts/microblaze.dts b/board/xilinx/microblaze-generic/dts/microblaze.dts
new file mode 100644
index 0000000..2033309
--- /dev/null
+++ b/board/xilinx/microblaze-generic/dts/microblaze.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	aliases {
+	} ;
+} ;
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index c20f1f2..cd3f9fa 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -44,6 +44,8 @@
 COBJS-$(CONFIG_SH_SPI) += sh_spi.o
 COBJS-$(CONFIG_FSL_ESPI) += fsl_espi.o
 COBJS-$(CONFIG_TEGRA_SPI) += tegra_spi.o
+COBJS-$(CONFIG_TEGRA2_SPI) += tegra2_spi.o
+COBJS-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c
new file mode 100644
index 0000000..e563c19
--- /dev/null
+++ b/drivers/spi/xilinx_spi.c
@@ -0,0 +1,214 @@
+/*
+ * Xilinx SPI driver
+ *
+ * supports 8 bit SPI transfers only, with or w/o FIFO
+ *
+ * based on bfin_spi.c, by way of altera_spi.c
+ * Copyright (c) 2005-2008 Analog Devices Inc.
+ * Copyright (c) 2010 Thomas Chou <thomas@wytron.com.tw>
+ * Copyright (c) 2010 Graeme Smecher <graeme.smecher@mail.mcgill.ca>
+ * Copyright (c) 2012 Stephan Linz <linz@li-pro.net>
+ *
+ * Licensed under the GPL-2 or later.
+ *
+ * [0]: http://www.xilinx.com/support/documentation
+ *
+ * [S]:	[0]/ip_documentation/xps_spi.pdf
+ *	[0]/ip_documentation/axi_spi_ds742.pdf
+ */
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <spi.h>
+
+#include "xilinx_spi.h"
+
+#ifndef CONFIG_SYS_XILINX_SPI_LIST
+#define CONFIG_SYS_XILINX_SPI_LIST	{ CONFIG_SYS_SPI_BASE }
+#endif
+
+#ifndef CONFIG_XILINX_SPI_IDLE_VAL
+#define CONFIG_XILINX_SPI_IDLE_VAL	0xff
+#endif
+
+#define XILSPI_SPICR_DFLT_ON		(SPICR_MANUAL_SS | \
+					 SPICR_MASTER_MODE | \
+					 SPICR_SPE)
+
+#define XILSPI_SPICR_DFLT_OFF		(SPICR_MASTER_INHIBIT | \
+					 SPICR_MANUAL_SS)
+
+#define XILSPI_MAX_XFER_BITS		8
+
+static unsigned long xilinx_spi_base_list[] = CONFIG_SYS_XILINX_SPI_LIST;
+
+__attribute__((weak))
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+	return bus < ARRAY_SIZE(xilinx_spi_base_list) && cs < 32;
+}
+
+__attribute__((weak))
+void spi_cs_activate(struct spi_slave *slave)
+{
+	struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave);
+
+	writel(SPISSR_ACT(slave->cs), &xilspi->regs->spissr);
+}
+
+__attribute__((weak))
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+	struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave);
+
+	writel(SPISSR_OFF, &xilspi->regs->spissr);
+}
+
+void spi_init(void)
+{
+	/* do nothing */
+}
+
+void spi_set_speed(struct spi_slave *slave, uint hz)
+{
+	/* xilinx spi core does not support programmable speed */
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+				  unsigned int max_hz, unsigned int mode)
+{
+	struct xilinx_spi_slave *xilspi;
+	struct xilinx_spi_reg *regs;
+
+	if (!spi_cs_is_valid(bus, cs)) {
+		printf("XILSPI error: %s: unsupported bus %d / cs %d\n",
+				__func__, bus, cs);
+		return NULL;
+	}
+
+	xilspi = malloc(sizeof(*xilspi));
+	if (!xilspi) {
+		printf("XILSPI error: %s: malloc of SPI structure failed\n",
+				__func__);
+		return NULL;
+	}
+	xilspi->slave.bus = bus;
+	xilspi->slave.cs = cs;
+	xilspi->regs = (struct xilinx_spi_reg *)xilinx_spi_base_list[bus];
+	xilspi->freq = max_hz;
+	xilspi->mode = mode;
+	debug("%s: bus:%i cs:%i base:%p mode:%x max_hz:%d\n", __func__,
+		bus, cs, xilspi->regs, xilspi->mode, xilspi->freq);
+
+	return &xilspi->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+	struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave);
+
+	free(xilspi);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+	struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave);
+	u32 spicr;
+
+	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
+	writel(SPISSR_OFF, &xilspi->regs->spissr);
+
+	spicr = XILSPI_SPICR_DFLT_ON;
+	if (xilspi->mode & SPI_LSB_FIRST)
+		spicr |= SPICR_LSB_FIRST;
+	if (xilspi->mode & SPI_CPHA)
+		spicr |= SPICR_CPHA;
+	if (xilspi->mode & SPI_CPOL)
+		spicr |= SPICR_CPOL;
+	if (xilspi->mode & SPI_LOOP)
+		spicr |= SPICR_LOOP;
+
+	writel(spicr, &xilspi->regs->spicr);
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+	struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave);
+
+	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
+	writel(SPISSR_OFF, &xilspi->regs->spissr);
+	writel(XILSPI_SPICR_DFLT_OFF, &xilspi->regs->spicr);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+	     void *din, unsigned long flags)
+{
+	struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave);
+	/* assume spi core configured to do 8 bit transfers */
+	unsigned int bytes = bitlen / XILSPI_MAX_XFER_BITS;
+	const unsigned char *txp = dout;
+	unsigned char *rxp = din;
+	unsigned rxecount = 17;	/* max. 16 elements in FIFO, leftover 1 */
+
+	debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
+		slave->bus, slave->cs, bitlen, bytes, flags);
+	if (bitlen == 0)
+		goto done;
+
+	if (bitlen % XILSPI_MAX_XFER_BITS) {
+		printf("XILSPI warning: %s: Not a multiple of %d bits\n",
+				__func__, XILSPI_MAX_XFER_BITS);
+		flags |= SPI_XFER_END;
+		goto done;
+	}
+
+	/* empty read buffer */
+	while (rxecount && !(readl(&xilspi->regs->spisr) & SPISR_RX_EMPTY)) {
+		readl(&xilspi->regs->spidrr);
+		rxecount--;
+	}
+
+	if (!rxecount) {
+		printf("XILSPI error: %s: Rx buffer not empty\n", __func__);
+		return -1;
+	}
+
+	if (flags & SPI_XFER_BEGIN)
+		spi_cs_activate(slave);
+
+	while (bytes--) {
+		unsigned timeout = /* at least 1usec or greater, leftover 1 */
+			xilspi->freq > XILSPI_MAX_XFER_BITS * 1000000 ? 2 :
+			(XILSPI_MAX_XFER_BITS * 1000000 / xilspi->freq) + 1;
+
+		/* get Tx element from data out buffer and count up */
+		unsigned char d = txp ? *txp++ : CONFIG_XILINX_SPI_IDLE_VAL;
+		debug("%s: tx:%x ", __func__, d);
+
+		/* write out and wait for processing (receive data) */
+		writel(d & SPIDTR_8BIT_MASK, &xilspi->regs->spidtr);
+		while (timeout && readl(&xilspi->regs->spisr)
+						& SPISR_RX_EMPTY) {
+			timeout--;
+			udelay(1);
+		}
+
+		if (!timeout) {
+			printf("XILSPI error: %s: Xfer timeout\n", __func__);
+			return -1;
+		}
+
+		/* read Rx element and push into data in buffer */
+		d = readl(&xilspi->regs->spidrr) & SPIDRR_8BIT_MASK;
+		if (rxp)
+			*rxp++ = d;
+		debug("rx:%x\n", d);
+	}
+
+ done:
+	if (flags & SPI_XFER_END)
+		spi_cs_deactivate(slave);
+
+	return 0;
+}
diff --git a/drivers/spi/xilinx_spi.h b/drivers/spi/xilinx_spi.h
new file mode 100644
index 0000000..32610d2
--- /dev/null
+++ b/drivers/spi/xilinx_spi.h
@@ -0,0 +1,135 @@
+/*
+ * Xilinx SPI driver
+ *
+ * XPS/AXI bus interface
+ *
+ * based on bfin_spi.c, by way of altera_spi.c
+ * Copyright (c) 2005-2008 Analog Devices Inc.
+ * Copyright (c) 2010 Thomas Chou <thomas@wytron.com.tw>
+ * Copyright (c) 2010 Graeme Smecher <graeme.smecher@mail.mcgill.ca>
+ * Copyright (c) 2012 Stephan Linz <linz@li-pro.net>
+ *
+ * Licensed under the GPL-2 or later.
+ *
+ * [0]: http://www.xilinx.com/support/documentation
+ *
+ * [S]:	[0]/ip_documentation/xps_spi.pdf
+ *	[0]/ip_documentation/axi_spi_ds742.pdf
+ */
+#ifndef _XILINX_SPI_
+#define _XILINX_SPI_
+
+#include <asm/types.h>
+#include <asm/io.h>
+
+/*
+ * Xilinx SPI Register Definition
+ *
+ * [1]:	[0]/ip_documentation/xps_spi.pdf
+ *	page 8, Register Descriptions
+ * [2]:	[0]/ip_documentation/axi_spi_ds742.pdf
+ *	page 7, Register Overview Table
+ */
+struct xilinx_spi_reg {
+	u32 __space0__[7];
+	u32 dgier;	/* Device Global Interrupt Enable Register (DGIER) */
+	u32 ipisr;	/* IP Interrupt Status Register (IPISR) */
+	u32 __space1__;
+	u32 ipier;	/* IP Interrupt Enable Register (IPIER) */
+	u32 __space2__[5];
+	u32 srr;	/* Softare Reset Register (SRR) */
+	u32 __space3__[7];
+	u32 spicr;	/* SPI Control Register (SPICR) */
+	u32 spisr;	/* SPI Status Register (SPISR) */
+	u32 spidtr;	/* SPI Data Transmit Register (SPIDTR) */
+	u32 spidrr;	/* SPI Data Receive Register (SPIDRR) */
+	u32 spissr;	/* SPI Slave Select Register (SPISSR) */
+	u32 spitfor;	/* SPI Transmit FIFO Occupancy Register (SPITFOR) */
+	u32 spirfor;	/* SPI Receive FIFO Occupancy Register (SPIRFOR) */
+};
+
+/* Device Global Interrupt Enable Register (dgier), [1] p15, [2] p15 */
+#define DGIER_GIE		(1 << 31)
+
+/* IP Interrupt Status Register (ipisr), [1] p15, [2] p15 */
+#define IPISR_DRR_NOT_EMPTY	(1 << 8)
+#define IPISR_SLAVE_SELECT	(1 << 7)
+#define IPISR_TXF_HALF_EMPTY	(1 << 6)
+#define IPISR_DRR_OVERRUN	(1 << 5)
+#define IPISR_DRR_FULL		(1 << 4)
+#define IPISR_DTR_UNDERRUN	(1 << 3)
+#define IPISR_DTR_EMPTY		(1 << 2)
+#define IPISR_SLAVE_MODF	(1 << 1)
+#define IPISR_MODF		(1 << 0)
+
+/* IP Interrupt Enable Register (ipier), [1] p17, [2] p18 */
+#define IPIER_DRR_NOT_EMPTY	(1 << 8)
+#define IPIER_SLAVE_SELECT	(1 << 7)
+#define IPIER_TXF_HALF_EMPTY	(1 << 6)
+#define IPIER_DRR_OVERRUN	(1 << 5)
+#define IPIER_DRR_FULL		(1 << 4)
+#define IPIER_DTR_UNDERRUN	(1 << 3)
+#define IPIER_DTR_EMPTY		(1 << 2)
+#define IPIER_SLAVE_MODF	(1 << 1)
+#define IPIER_MODF		(1 << 0)
+
+/* Softare Reset Register (srr), [1] p9, [2] p8 */
+#define SRR_RESET_CODE		0x0000000A
+
+/* SPI Control Register (spicr), [1] p9, [2] p8 */
+#define SPICR_LSB_FIRST		(1 << 9)
+#define SPICR_MASTER_INHIBIT	(1 << 8)
+#define SPICR_MANUAL_SS		(1 << 7)
+#define SPICR_RXFIFO_RESEST	(1 << 6)
+#define SPICR_TXFIFO_RESEST	(1 << 5)
+#define SPICR_CPHA		(1 << 4)
+#define SPICR_CPOL		(1 << 3)
+#define SPICR_MASTER_MODE	(1 << 2)
+#define SPICR_SPE		(1 << 1)
+#define SPICR_LOOP		(1 << 0)
+
+/* SPI Status Register (spisr), [1] p11, [2] p10 */
+#define SPISR_SLAVE_MODE_SELECT	(1 << 5)
+#define SPISR_MODF		(1 << 4)
+#define SPISR_TX_FULL		(1 << 3)
+#define SPISR_TX_EMPTY		(1 << 2)
+#define SPISR_RX_FULL		(1 << 1)
+#define SPISR_RX_EMPTY		(1 << 0)
+
+/* SPI Data Transmit Register (spidtr), [1] p12, [2] p12 */
+#define SPIDTR_8BIT_MASK	(0xff << 0)
+#define SPIDTR_16BIT_MASK	(0xffff << 0)
+#define SPIDTR_32BIT_MASK	(0xffffffff << 0)
+
+/* SPI Data Receive Register (spidrr), [1] p12, [2] p12 */
+#define SPIDRR_8BIT_MASK	(0xff << 0)
+#define SPIDRR_16BIT_MASK	(0xffff << 0)
+#define SPIDRR_32BIT_MASK	(0xffffffff << 0)
+
+/* SPI Slave Select Register (spissr), [1] p13, [2] p13 */
+#define SPISSR_MASK(cs)		(1 << (cs))
+#define SPISSR_ACT(cs)		~SPISSR_MASK(cs)
+#define SPISSR_OFF		~0UL
+
+/* SPI Transmit FIFO Occupancy Register (spitfor), [1] p13, [2] p14 */
+#define SPITFOR_OCYVAL_POS	0
+#define SPITFOR_OCYVAL_MASK	(0xf << SPITFOR_OCYVAL_POS)
+
+/* SPI Receive FIFO Occupancy Register (spirfor), [1] p14, [2] p14 */
+#define SPIRFOR_OCYVAL_POS	0
+#define SPIRFOR_OCYVAL_MASK	(0xf << SPIRFOR_OCYVAL_POS)
+
+struct xilinx_spi_slave {
+	struct spi_slave slave;
+	struct xilinx_spi_reg *regs;
+	unsigned int freq;
+	unsigned int mode;
+};
+
+static inline struct xilinx_spi_slave *to_xilinx_spi_slave(
+					struct spi_slave *slave)
+{
+	return container_of(slave, struct xilinx_spi_slave, slave);
+}
+
+#endif /* _XILINX_SPI_ */
diff --git a/dts/Makefile b/dts/Makefile
index 402dfe1..055b8ac 100644
--- a/dts/Makefile
+++ b/dts/Makefile
@@ -36,7 +36,8 @@
 Please define CONFIG_ARCH_DEVICE_TREE))
 
 # We preprocess the device tree file provide a useful define
-DTS_CPPFLAGS := -DARCH_CPU_DTS=\"$(SRCTREE)/arch/$(ARCH)/dts/$(CONFIG_ARCH_DEVICE_TREE).dtsi\"
+DTS_CPPFLAGS := -DARCH_CPU_DTS=\"$(SRCTREE)/arch/$(ARCH)/dts/$(CONFIG_ARCH_DEVICE_TREE).dtsi\" \
+		-DBOARD_DTS=\"$(SRCTREE)/board/$(VENDOR)/$(BOARD)/dts/$(DEVICE_TREE).dts\"
 
 all:	$(obj).depend $(LIB)
 
diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h
index 295d123..1266cf7 100644
--- a/include/configs/microblaze-generic.h
+++ b/include/configs/microblaze-generic.h
@@ -31,6 +31,28 @@
 #define	CONFIG_MICROBLAZE	1
 #define	MICROBLAZE_V5		1
 
+/* Open Firmware DTS */
+#define CONFIG_OF_CONTROL	1
+#define CONFIG_OF_EMBED		1
+#define CONFIG_DEFAULT_DEVICE_TREE microblaze
+
+/* linear and spi flash memory */
+#ifdef XILINX_FLASH_START
+#define	FLASH
+#undef	SPIFLASH
+#undef	RAMENV	/* hold environment in flash */
+#else
+#ifdef XILINX_SPI_FLASH_BASEADDR
+#undef	FLASH
+#define	SPIFLASH
+#undef	RAMENV	/* hold environment in flash */
+#else
+#undef	FLASH
+#undef	SPIFLASH
+#define	RAMENV	/* hold environment in RAM */
+#endif
+#endif
+
 /* uart */
 #ifdef XILINX_UARTLITE_BASEADDR
 # define CONFIG_XILINX_UARTLITE
@@ -88,7 +110,6 @@
 
 /* interrupt controller */
 #ifdef XILINX_INTC_BASEADDR
-# define CONFIG_SYS_INTC_0		1
 # define CONFIG_SYS_INTC_0_ADDR		XILINX_INTC_BASEADDR
 # define CONFIG_SYS_INTC_0_NUM		XILINX_INTC_NUM_INTR_INPUTS
 #endif
@@ -113,15 +134,19 @@
 
 /*
  * memory layout - Example
- * CONFIG_SYS_TEXT_BASE = 0x1200_0000;
+ * CONFIG_SYS_TEXT_BASE = 0x1200_0000;	defined in config.mk
  * CONFIG_SYS_SRAM_BASE = 0x1000_0000;
- * CONFIG_SYS_SRAM_SIZE = 0x0400_0000;
+ * CONFIG_SYS_SRAM_SIZE = 0x0400_0000;	64MB
+ *
+ * CONFIG_SYS_MONITOR_LEN = 0x40000
+ * CONFIG_SYS_MALLOC_LEN = 3 * CONFIG_SYS_MONITOR_LEN = 0xC0000
  *
  * CONFIG_SYS_GBL_DATA_OFFSET = 0x1000_0000 + 0x0400_0000 - 0x1000 = 0x13FF_F000
- * CONFIG_SYS_MONITOR_BASE = 0x13FF_F000 - 0x40000 = 0x13FB_F000
- * CONFIG_SYS_MALLOC_BASE = 0x13FB_F000 - 0x40000 = 0x13F7_F000
+ * CONFIG_SYS_MONITOR_BASE = 0x13FF_F000 - CONFIG_SYS_MONITOR_LEN = 0x13FB_F000
+ * CONFIG_SYS_MALLOC_BASE = 0x13FB_F000 - CONFIG_SYS_MALLOC_LEN = 0x13EF_F000
  *
  * 0x1000_0000	CONFIG_SYS_SDRAM_BASE
+ *					MEMTEST_AREA	 64kB
  *					FREE
  * 0x1200_0000	CONFIG_SYS_TEXT_BASE
  *		U-BOOT code
@@ -129,9 +154,9 @@
  *					FREE
  *
  *					STACK
- * 0x13F7_F000	CONFIG_SYS_MALLOC_BASE
- *					MALLOC_AREA	256kB	Alloc
- * 0x11FB_F000	CONFIG_SYS_MONITOR_BASE
+ * 0x13EF_F000	CONFIG_SYS_MALLOC_BASE
+ *					MALLOC_AREA	768kB	Alloc
+ * 0x13FB_F000	CONFIG_SYS_MONITOR_BASE
  *					MONITOR_CODE	256kB	Env
  * 0x13FF_F000	CONFIG_SYS_GBL_DATA_OFFSET
  *					GLOBAL_DATA	4kB	bd, gd
@@ -157,15 +182,30 @@
 			- CONFIG_SYS_MONITOR_LEN - GENERATED_BD_INFO_SIZE)
 #define	CONFIG_SYS_MONITOR_END \
 			(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN)
-#define	CONFIG_SYS_MALLOC_LEN		SIZE
+#define	CONFIG_SYS_MALLOC_LEN		(SIZE * 3)
 #define	CONFIG_SYS_MALLOC_BASE \
 			(CONFIG_SYS_MONITOR_BASE - CONFIG_SYS_MALLOC_LEN)
 
 /* stack */
 #define	CONFIG_SYS_INIT_SP_OFFSET	CONFIG_SYS_MALLOC_BASE
 
-/*#define	RAMENV */
-#define	FLASH
+/*
+ * CFI flash memory layout - Example
+ * CONFIG_SYS_FLASH_BASE = 0x2200_0000;
+ * CONFIG_SYS_FLASH_SIZE = 0x0080_0000;	  8MB
+ *
+ * SECT_SIZE = 0x20000;			128kB is one sector
+ * CONFIG_ENV_SIZE = SECT_SIZE;		128kB environment store
+ *
+ * 0x2200_0000	CONFIG_SYS_FLASH_BASE
+ *					FREE		256kB
+ * 0x2204_0000	CONFIG_ENV_ADDR
+ *					ENV_AREA	128kB
+ * 0x2206_0000
+ *					FREE
+ * 0x2280_0000	CONFIG_SYS_FLASH_BASE + CONFIG_SYS_FLASH_SIZE
+ *
+ */
 
 #ifdef FLASH
 # define CONFIG_SYS_FLASH_BASE		XILINX_FLASH_START
@@ -186,22 +226,51 @@
 #  define CONFIG_ENV_SIZE	0x1000
 #  define CONFIG_ENV_ADDR	(CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SIZE)
 
-# else	/* !RAMENV */
+# else	/* FLASH && !RAMENV */
 #  define CONFIG_ENV_IS_IN_FLASH	1
 /* 128K(one sector) for env */
 #  define CONFIG_ENV_SECT_SIZE	0x20000
 #  define CONFIG_ENV_ADDR \
 			(CONFIG_SYS_FLASH_BASE + (2 * CONFIG_ENV_SECT_SIZE))
 #  define CONFIG_ENV_SIZE	0x20000
-# endif /* !RAMBOOT */
+# endif /* FLASH && !RAMBOOT */
 #else /* !FLASH */
+
+#ifdef SPIFLASH
+# define CONFIG_SYS_NO_FLASH		1
+# define CONFIG_SYS_SPI_BASE		XILINX_SPI_FLASH_BASEADDR
+# define CONFIG_XILINX_SPI		1
+# define CONFIG_SPI			1
+# define CONFIG_SPI_FLASH		1
+# define CONFIG_SPI_FLASH_STMICRO	1
+# define CONFIG_SF_DEFAULT_MODE		SPI_MODE_3
+# define CONFIG_SF_DEFAULT_SPEED	XILINX_SPI_FLASH_MAX_FREQ
+# define CONFIG_SF_DEFAULT_CS		XILINX_SPI_FLASH_CS
+
+# ifdef	RAMENV
+#  define CONFIG_ENV_IS_NOWHERE	1
+#  define CONFIG_ENV_SIZE	0x1000
+#  define CONFIG_ENV_ADDR	(CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SIZE)
+
+# else	/* SPIFLASH && !RAMENV */
+#  define CONFIG_ENV_IS_IN_SPI_FLASH	1
+#  define CONFIG_ENV_SPI_MODE		SPI_MODE_3
+#  define CONFIG_ENV_SPI_MAX_HZ		CONFIG_SF_DEFAULT_SPEED
+#  define CONFIG_ENV_SPI_CS		CONFIG_SF_DEFAULT_CS
+/* 128K(two sectors) for env */
+#  define CONFIG_ENV_SECT_SIZE	0x10000
+#  define CONFIG_ENV_SIZE	(2 * CONFIG_ENV_SECT_SIZE)
+/* Warning: adjust the offset in respect of other flash content and size */
+#  define CONFIG_ENV_OFFSET	(128 * CONFIG_ENV_SECT_SIZE) /* at 8MB */
+# endif /* SPIFLASH && !RAMBOOT */
+#else /* !SPIFLASH */
+
 /* ENV in RAM */
 # define CONFIG_SYS_NO_FLASH	1
 # define CONFIG_ENV_IS_NOWHERE	1
 # define CONFIG_ENV_SIZE	0x1000
 # define CONFIG_ENV_ADDR	(CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SIZE)
-/* hardware flash protection */
-# define CONFIG_SYS_FLASH_PROTECTION
+#endif /* !SPIFLASH */
 #endif /* !FLASH */
 
 /* system ace */
@@ -269,6 +338,17 @@
 # define CONFIG_CMD_FLASH
 # define CONFIG_CMD_IMLS
 # define CONFIG_CMD_JFFS2
+# define CONFIG_CMD_UBI
+# undef CONFIG_CMD_UBIFS
+
+# if !defined(RAMENV)
+#  define CONFIG_CMD_SAVEENV
+#  define CONFIG_CMD_SAVES
+# endif
+
+#else
+#if defined(SPIFLASH)
+# define CONFIG_CMD_SF
 
 # if !defined(RAMENV)
 #  define CONFIG_CMD_SAVEENV
@@ -278,10 +358,27 @@
 # undef CONFIG_CMD_IMLS
 # undef CONFIG_CMD_FLASH
 # undef CONFIG_CMD_JFFS2
+# undef CONFIG_CMD_UBI
+# undef CONFIG_CMD_UBIFS
+#endif
 #endif
 
 #if defined(CONFIG_CMD_JFFS2)
-/* JFFS2 partitions */
+# define CONFIG_MTD_PARTITIONS
+#endif
+
+#if defined(CONFIG_CMD_UBIFS)
+# define CONFIG_CMD_UBI
+# define CONFIG_LZO
+#endif
+
+#if defined(CONFIG_CMD_UBI)
+# define CONFIG_MTD_PARTITIONS
+# define CONFIG_RBTREE
+#endif
+
+#if defined(CONFIG_MTD_PARTITIONS)
+/* MTD partitions */
 #define CONFIG_CMD_MTDPARTS	/* mtdparts command line support */
 #define CONFIG_MTD_DEVICE	/* needed for mtdparts commands */
 #define CONFIG_FLASH_CFI_MTD