Browse Source

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

Tom Rini 10 years ago
parent
commit
cc555bd4f4

+ 0 - 11
README

@@ -3096,17 +3096,6 @@ CBFS (Coreboot Filesystem) support
 		memories can be connected with a given cs line.
 		memories can be connected with a given cs line.
 		Currently Xilinx Zynq qspi supports these type of connections.
 		Currently Xilinx Zynq qspi supports these type of connections.
 
 
-		CONFIG_SYS_SPI_ST_ENABLE_WP_PIN
-		enable the W#/Vpp signal to disable writing to the status
-		register on ST MICRON flashes like the N25Q128.
-		The status register write enable/disable bit, combined with
-		the W#/VPP signal provides hardware data protection for the
-		device as follows: When the enable/disable bit is set to 1,
-		and the W#/VPP signal is driven LOW, the status register
-		nonvolatile bits become read-only and the WRITE STATUS REGISTER
-		operation will not execute. The only way to exit this
-		hardware-protected mode is to drive W#/VPP HIGH.
-
 - SystemACE Support:
 - SystemACE Support:
 		CONFIG_SYSTEMACE
 		CONFIG_SYSTEMACE
 
 

+ 8 - 8
common/cmd_sf.c

@@ -164,6 +164,8 @@ static int do_spi_flash_probe(int argc, char * const argv[])
 static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset,
 static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset,
 		size_t len, const char *buf, char *cmp_buf, size_t *skipped)
 		size_t len, const char *buf, char *cmp_buf, size_t *skipped)
 {
 {
+	char *ptr = (char *)buf;
+
 	debug("offset=%#x, sector_size=%#x, len=%#zx\n",
 	debug("offset=%#x, sector_size=%#x, len=%#zx\n",
 	      offset, flash->sector_size, len);
 	      offset, flash->sector_size, len);
 	/* Read the entire sector so to allow for rewriting */
 	/* Read the entire sector so to allow for rewriting */
@@ -179,16 +181,14 @@ static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset,
 	/* Erase the entire sector */
 	/* Erase the entire sector */
 	if (spi_flash_erase(flash, offset, flash->sector_size))
 	if (spi_flash_erase(flash, offset, flash->sector_size))
 		return "erase";
 		return "erase";
-	/* Write the initial part of the block from the source */
-	if (spi_flash_write(flash, offset, len, buf))
-		return "write";
-	/* If it's a partial sector, rewrite the existing part */
+	/* If it's a partial sector, copy the data into the temp-buffer */
 	if (len != flash->sector_size) {
 	if (len != flash->sector_size) {
-		/* Rewrite the original data to the end of the sector */
-		if (spi_flash_write(flash, offset + len,
-				    flash->sector_size - len, &cmp_buf[len]))
-			return "write";
+		memcpy(cmp_buf, buf, len);
+		ptr = cmp_buf;
 	}
 	}
+	/* Write one complete sector */
+	if (spi_flash_write(flash, offset, flash->sector_size, ptr))
+		return "write";
 
 
 	return NULL;
 	return NULL;
 }
 }

+ 2 - 5
drivers/mtd/spi/sf_internal.h

@@ -97,10 +97,6 @@ enum {
 #define STATUS_QEB_MXIC		(1 << 6)
 #define STATUS_QEB_MXIC		(1 << 6)
 #define STATUS_PEC			(1 << 7)
 #define STATUS_PEC			(1 << 7)
 
 
-#ifdef CONFIG_SYS_SPI_ST_ENABLE_WP_PIN
-#define STATUS_SRWD			(1 << 7) /* SR write protect */
-#endif
-
 /* Flash timeout values */
 /* Flash timeout values */
 #define SPI_FLASH_PROG_TIMEOUT		(2 * CONFIG_SYS_HZ)
 #define SPI_FLASH_PROG_TIMEOUT		(2 * CONFIG_SYS_HZ)
 #define SPI_FLASH_PAGE_ERASE_TIMEOUT		(5 * CONFIG_SYS_HZ)
 #define SPI_FLASH_PAGE_ERASE_TIMEOUT		(5 * CONFIG_SYS_HZ)
@@ -123,7 +119,8 @@ int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len,
  * @name:		Device name ([MANUFLETTER][DEVTYPE][DENSITY][EXTRAINFO])
  * @name:		Device name ([MANUFLETTER][DEVTYPE][DENSITY][EXTRAINFO])
  * @jedec:		Device jedec ID (0x[1byte_manuf_id][2byte_dev_id])
  * @jedec:		Device jedec ID (0x[1byte_manuf_id][2byte_dev_id])
  * @ext_jedec:		Device ext_jedec ID
  * @ext_jedec:		Device ext_jedec ID
- * @sector_size:	Sector size of this device
+ * @sector_size:	Isn't necessarily a sector size from vendor,
+ *			the size listed here is what works with CMD_ERASE_64K
  * @nr_sectors:	No.of sectors on this device
  * @nr_sectors:	No.of sectors on this device
  * @e_rd_cmd:		Enum list for read commands
  * @e_rd_cmd:		Enum list for read commands
  * @flags:		Important param, for flash specific behaviour
  * @flags:		Important param, for flash specific behaviour

+ 25 - 7
drivers/mtd/spi/sf_ops.c

@@ -154,21 +154,17 @@ static void spi_flash_dual_flash(struct spi_flash *flash, u32 *addr)
 }
 }
 #endif
 #endif
 
 
-int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
+static int spi_flash_poll_status(struct spi_slave *spi, unsigned long timeout,
+				 u8 cmd, u8 poll_bit)
 {
 {
-	struct spi_slave *spi = flash->spi;
 	unsigned long timebase;
 	unsigned long timebase;
 	unsigned long flags = SPI_XFER_BEGIN;
 	unsigned long flags = SPI_XFER_BEGIN;
 	int ret;
 	int ret;
 	u8 status;
 	u8 status;
 	u8 check_status = 0x0;
 	u8 check_status = 0x0;
-	u8 poll_bit = STATUS_WIP;
-	u8 cmd = flash->poll_cmd;
 
 
-	if (cmd == CMD_FLAG_STATUS) {
-		poll_bit = STATUS_PEC;
+	if (cmd == CMD_FLAG_STATUS)
 		check_status = poll_bit;
 		check_status = poll_bit;
-	}
 
 
 #ifdef CONFIG_SF_DUAL_FLASH
 #ifdef CONFIG_SF_DUAL_FLASH
 	if (spi->flags & SPI_XFER_U_PAGE)
 	if (spi->flags & SPI_XFER_U_PAGE)
@@ -204,6 +200,28 @@ int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
 	return -1;
 	return -1;
 }
 }
 
 
+int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
+{
+	struct spi_slave *spi = flash->spi;
+	int ret;
+	u8 poll_bit = STATUS_WIP;
+	u8 cmd = CMD_READ_STATUS;
+
+	ret = spi_flash_poll_status(spi, timeout, cmd, poll_bit);
+	if (ret < 0)
+		return ret;
+
+	if (flash->poll_cmd == CMD_FLAG_STATUS) {
+		poll_bit = STATUS_PEC;
+		cmd = CMD_FLAG_STATUS;
+		ret = spi_flash_poll_status(spi, timeout, cmd, poll_bit);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
 int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
 int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
 		size_t cmd_len, const void *buf, size_t buf_len)
 		size_t cmd_len, const void *buf, size_t buf_len)
 {
 {

+ 19 - 30
drivers/mtd/spi/sf_probe.c

@@ -132,6 +132,9 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode,
 	flash->name = params->name;
 	flash->name = params->name;
 	flash->memory_map = spi->memory_map;
 	flash->memory_map = spi->memory_map;
 	flash->dual_flash = flash->spi->option;
 	flash->dual_flash = flash->spi->option;
+#ifdef CONFIG_DM_SPI_FLASH
+	flash->flags = params->flags;
+#endif
 
 
 	/* Assign spi_flash ops */
 	/* Assign spi_flash ops */
 #ifndef CONFIG_DM_SPI_FLASH
 #ifndef CONFIG_DM_SPI_FLASH
@@ -184,6 +187,9 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode,
 		flash->erase_size = flash->sector_size;
 		flash->erase_size = flash->sector_size;
 	}
 	}
 
 
+	/* Now erase size becomes valid sector size */
+	flash->sector_size = flash->erase_size;
+
 	/* Look for the fastest read cmd */
 	/* Look for the fastest read cmd */
 	cmd = fls(params->e_rd_cmd & flash->spi->op_mode_rx);
 	cmd = fls(params->e_rd_cmd & flash->spi->op_mode_rx);
 	if (cmd) {
 	if (cmd) {
@@ -288,34 +294,6 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
 }
 }
 #endif /* CONFIG_OF_CONTROL */
 #endif /* CONFIG_OF_CONTROL */
 
 
-#ifdef CONFIG_SYS_SPI_ST_ENABLE_WP_PIN
-/* enable the W#/Vpp signal to disable writing to the status register */
-static int spi_enable_wp_pin(struct spi_flash *flash)
-{
-	u8 status;
-	int ret;
-
-	ret = spi_flash_cmd_read_status(flash, &status);
-	if (ret < 0)
-		return ret;
-
-	ret = spi_flash_cmd_write_status(flash, STATUS_SRWD);
-	if (ret < 0)
-		return ret;
-
-	ret = spi_flash_cmd_write_disable(flash);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-#else
-static int spi_enable_wp_pin(struct spi_flash *flash)
-{
-	return 0;
-}
-#endif
-
 /**
 /**
  * spi_flash_probe_slave() - Probe for a SPI flash device on a bus
  * spi_flash_probe_slave() - Probe for a SPI flash device on a bus
  *
  *
@@ -394,8 +372,6 @@ int spi_flash_probe_slave(struct spi_slave *spi, struct spi_flash *flash)
 		puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
 		puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
 	}
 	}
 #endif
 #endif
-	if (spi_enable_wp_pin(flash))
-		puts("Enable WP pin failed\n");
 
 
 	/* Release spi bus */
 	/* Release spi bus */
 	spi_release_bus(spi);
 	spi_release_bus(spi);
@@ -434,6 +410,8 @@ struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
 	struct spi_slave *bus;
 	struct spi_slave *bus;
 
 
 	bus = spi_setup_slave(busnum, cs, max_hz, spi_mode);
 	bus = spi_setup_slave(busnum, cs, max_hz, spi_mode);
+	if (!bus)
+		return NULL;
 	return spi_flash_probe_tail(bus);
 	return spi_flash_probe_tail(bus);
 }
 }
 
 
@@ -444,6 +422,8 @@ struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,
 	struct spi_slave *bus;
 	struct spi_slave *bus;
 
 
 	bus = spi_setup_slave_fdt(blob, slave_node, spi_node);
 	bus = spi_setup_slave_fdt(blob, slave_node, spi_node);
+	if (!bus)
+		return NULL;
 	return spi_flash_probe_tail(bus);
 	return spi_flash_probe_tail(bus);
 }
 }
 #endif
 #endif
@@ -469,6 +449,15 @@ int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len,
 {
 {
 	struct spi_flash *flash = dev_get_uclass_priv(dev);
 	struct spi_flash *flash = dev_get_uclass_priv(dev);
 
 
+#if defined(CONFIG_SPI_FLASH_SST)
+	if (flash->flags & SST_WR) {
+		if (flash->spi->op_mode_tx & SPI_OPM_TX_BP)
+			return sst_write_bp(flash, offset, len, buf);
+		else
+			return sst_write_wp(flash, offset, len, buf);
+	}
+#endif
+
 	return spi_flash_cmd_write_ops(flash, offset, len, buf);
 	return spi_flash_cmd_write_ops(flash, offset, len, buf);
 }
 }
 
 

+ 4 - 2
drivers/spi/exynos_spi.c

@@ -296,8 +296,9 @@ static int exynos_spi_probe(struct udevice *bus)
 	return 0;
 	return 0;
 }
 }
 
 
-static int exynos_spi_claim_bus(struct udevice *bus)
+static int exynos_spi_claim_bus(struct udevice *dev)
 {
 {
+	struct udevice *bus = dev->parent;
 	struct exynos_spi_priv *priv = dev_get_priv(bus);
 	struct exynos_spi_priv *priv = dev_get_priv(bus);
 
 
 	exynos_pinmux_config(priv->periph_id, PINMUX_FLAG_NONE);
 	exynos_pinmux_config(priv->periph_id, PINMUX_FLAG_NONE);
@@ -308,8 +309,9 @@ static int exynos_spi_claim_bus(struct udevice *bus)
 	return 0;
 	return 0;
 }
 }
 
 
-static int exynos_spi_release_bus(struct udevice *bus)
+static int exynos_spi_release_bus(struct udevice *dev)
 {
 {
+	struct udevice *bus = dev->parent;
 	struct exynos_spi_priv *priv = dev_get_priv(bus);
 	struct exynos_spi_priv *priv = dev_get_priv(bus);
 
 
 	spi_flush_fifo(priv->regs);
 	spi_flush_fifo(priv->regs);

+ 12 - 8
drivers/spi/omap3_spi.c

@@ -20,7 +20,7 @@
 #include <asm/io.h>
 #include <asm/io.h>
 #include "omap3_spi.h"
 #include "omap3_spi.h"
 
 
-#define SPI_WAIT_TIMEOUT 3000000
+#define SPI_WAIT_TIMEOUT 10
 
 
 static void spi_reset(struct omap3_spi_slave *ds)
 static void spi_reset(struct omap3_spi_slave *ds)
 {
 {
@@ -227,7 +227,7 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const void *txp,
 {
 {
 	struct omap3_spi_slave *ds = to_omap3_spi(slave);
 	struct omap3_spi_slave *ds = to_omap3_spi(slave);
 	int i;
 	int i;
-	int timeout = SPI_WAIT_TIMEOUT;
+	ulong start;
 	int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
 	int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
 
 
 	/* Enable the channel */
 	/* Enable the channel */
@@ -241,9 +241,10 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const void *txp,
 
 
 	for (i = 0; i < len; i++) {
 	for (i = 0; i < len; i++) {
 		/* wait till TX register is empty (TXS == 1) */
 		/* wait till TX register is empty (TXS == 1) */
+		start = get_timer(0);
 		while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
 		while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
 			 OMAP3_MCSPI_CHSTAT_TXS)) {
 			 OMAP3_MCSPI_CHSTAT_TXS)) {
-			if (--timeout <= 0) {
+			if (get_timer(start) > SPI_WAIT_TIMEOUT) {
 				printf("SPI TXS timed out, status=0x%08x\n",
 				printf("SPI TXS timed out, status=0x%08x\n",
 				       readl(&ds->regs->channel[ds->slave.cs].chstat));
 				       readl(&ds->regs->channel[ds->slave.cs].chstat));
 				return -1;
 				return -1;
@@ -280,7 +281,7 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, void *rxp,
 {
 {
 	struct omap3_spi_slave *ds = to_omap3_spi(slave);
 	struct omap3_spi_slave *ds = to_omap3_spi(slave);
 	int i;
 	int i;
-	int timeout = SPI_WAIT_TIMEOUT;
+	ulong start;
 	int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
 	int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
 
 
 	/* Enable the channel */
 	/* Enable the channel */
@@ -295,10 +296,11 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, void *rxp,
 	writel(0, &ds->regs->channel[ds->slave.cs].tx);
 	writel(0, &ds->regs->channel[ds->slave.cs].tx);
 
 
 	for (i = 0; i < len; i++) {
 	for (i = 0; i < len; i++) {
+		start = get_timer(0);
 		/* Wait till RX register contains data (RXS == 1) */
 		/* Wait till RX register contains data (RXS == 1) */
 		while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
 		while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
 			 OMAP3_MCSPI_CHSTAT_RXS)) {
 			 OMAP3_MCSPI_CHSTAT_RXS)) {
-			if (--timeout <= 0) {
+			if (get_timer(start) > SPI_WAIT_TIMEOUT) {
 				printf("SPI RXS timed out, status=0x%08x\n",
 				printf("SPI RXS timed out, status=0x%08x\n",
 				       readl(&ds->regs->channel[ds->slave.cs].chstat));
 				       readl(&ds->regs->channel[ds->slave.cs].chstat));
 				return -1;
 				return -1;
@@ -332,7 +334,7 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len,
 		   const void *txp, void *rxp, unsigned long flags)
 		   const void *txp, void *rxp, unsigned long flags)
 {
 {
 	struct omap3_spi_slave *ds = to_omap3_spi(slave);
 	struct omap3_spi_slave *ds = to_omap3_spi(slave);
-	int timeout = SPI_WAIT_TIMEOUT;
+	ulong start;
 	int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
 	int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
 	int irqstatus = readl(&ds->regs->irqstatus);
 	int irqstatus = readl(&ds->regs->irqstatus);
 	int i=0;
 	int i=0;
@@ -350,9 +352,10 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len,
 	for (i=0; i < len; i++){
 	for (i=0; i < len; i++){
 		/* Write: wait for TX empty (TXS == 1)*/
 		/* Write: wait for TX empty (TXS == 1)*/
 		irqstatus |= (1<< (4*(ds->slave.bus)));
 		irqstatus |= (1<< (4*(ds->slave.bus)));
+		start = get_timer(0);
 		while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
 		while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
 			 OMAP3_MCSPI_CHSTAT_TXS)) {
 			 OMAP3_MCSPI_CHSTAT_TXS)) {
-			if (--timeout <= 0) {
+			if (get_timer(start) > SPI_WAIT_TIMEOUT) {
 				printf("SPI TXS timed out, status=0x%08x\n",
 				printf("SPI TXS timed out, status=0x%08x\n",
 				       readl(&ds->regs->channel[ds->slave.cs].chstat));
 				       readl(&ds->regs->channel[ds->slave.cs].chstat));
 				return -1;
 				return -1;
@@ -368,9 +371,10 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len,
 			writel(((u8 *)txp)[i], tx);
 			writel(((u8 *)txp)[i], tx);
 
 
 		/*Read: wait for RX containing data (RXS == 1)*/
 		/*Read: wait for RX containing data (RXS == 1)*/
+		start = get_timer(0);
 		while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
 		while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
 			 OMAP3_MCSPI_CHSTAT_RXS)) {
 			 OMAP3_MCSPI_CHSTAT_RXS)) {
-			if (--timeout <= 0) {
+			if (get_timer(start) > SPI_WAIT_TIMEOUT) {
 				printf("SPI RXS timed out, status=0x%08x\n",
 				printf("SPI RXS timed out, status=0x%08x\n",
 				       readl(&ds->regs->channel[ds->slave.cs].chstat));
 				       readl(&ds->regs->channel[ds->slave.cs].chstat));
 				return -1;
 				return -1;

+ 2 - 2
drivers/spi/spi-uclass.c

@@ -67,7 +67,7 @@ int spi_claim_bus(struct spi_slave *slave)
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	return ops->claim_bus ? ops->claim_bus(bus) : 0;
+	return ops->claim_bus ? ops->claim_bus(dev) : 0;
 }
 }
 
 
 void spi_release_bus(struct spi_slave *slave)
 void spi_release_bus(struct spi_slave *slave)
@@ -77,7 +77,7 @@ void spi_release_bus(struct spi_slave *slave)
 	struct dm_spi_ops *ops = spi_get_ops(bus);
 	struct dm_spi_ops *ops = spi_get_ops(bus);
 
 
 	if (ops->release_bus)
 	if (ops->release_bus)
-		ops->release_bus(bus);
+		ops->release_bus(dev);
 }
 }
 
 
 int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 int spi_xfer(struct spi_slave *slave, unsigned int bitlen,

+ 2 - 1
drivers/spi/tegra114_spi.c

@@ -153,8 +153,9 @@ static int tegra114_spi_probe(struct udevice *bus)
 	return 0;
 	return 0;
 }
 }
 
 
-static int tegra114_spi_claim_bus(struct udevice *bus)
+static int tegra114_spi_claim_bus(struct udevice *dev)
 {
 {
+	struct udevice *bus = dev->parent;
 	struct tegra114_spi_priv *priv = dev_get_priv(bus);
 	struct tegra114_spi_priv *priv = dev_get_priv(bus);
 	struct spi_regs *regs = priv->regs;
 	struct spi_regs *regs = priv->regs;
 
 

+ 2 - 1
drivers/spi/tegra20_sflash.c

@@ -125,8 +125,9 @@ static int tegra20_sflash_probe(struct udevice *bus)
 	return 0;
 	return 0;
 }
 }
 
 
-static int tegra20_sflash_claim_bus(struct udevice *bus)
+static int tegra20_sflash_claim_bus(struct udevice *dev)
 {
 {
+	struct udevice *bus = dev->parent;
 	struct tegra20_sflash_priv *priv = dev_get_priv(bus);
 	struct tegra20_sflash_priv *priv = dev_get_priv(bus);
 	struct spi_regs *regs = priv->regs;
 	struct spi_regs *regs = priv->regs;
 	u32 reg;
 	u32 reg;

+ 2 - 1
drivers/spi/tegra20_slink.c

@@ -141,8 +141,9 @@ static int tegra30_spi_probe(struct udevice *bus)
 	return 0;
 	return 0;
 }
 }
 
 
-static int tegra30_spi_claim_bus(struct udevice *bus)
+static int tegra30_spi_claim_bus(struct udevice *dev)
 {
 {
+	struct udevice *bus = dev->parent;
 	struct tegra30_spi_priv *priv = dev_get_priv(bus);
 	struct tegra30_spi_priv *priv = dev_get_priv(bus);
 	struct spi_regs *regs = priv->regs;
 	struct spi_regs *regs = priv->regs;
 	u32 reg;
 	u32 reg;

+ 0 - 3
drivers/spi/zynq_spi.c

@@ -227,9 +227,6 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
 	debug("spi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n",
 	debug("spi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n",
 	      slave->bus, slave->cs, bitlen, len, flags);
 	      slave->bus, slave->cs, bitlen, len, flags);
 
 
-	if (bitlen == 0)
-		return -1;
-
 	if (bitlen % 8) {
 	if (bitlen % 8) {
 		debug("spi_xfer: Non byte aligned SPI transfer\n");
 		debug("spi_xfer: Non byte aligned SPI transfer\n");
 		return -1;
 		return -1;

+ 11 - 10
include/spi.h

@@ -38,11 +38,12 @@
 
 
 /* SPI RX operation modes */
 /* SPI RX operation modes */
 #define SPI_OPM_RX_AS		(1 << 0)
 #define SPI_OPM_RX_AS		(1 << 0)
-#define SPI_OPM_RX_DOUT	(1 << 1)
-#define SPI_OPM_RX_DIO		(1 << 2)
-#define SPI_OPM_RX_QOF		(1 << 3)
-#define SPI_OPM_RX_QIOF	(1 << 4)
-#define SPI_OPM_RX_EXTN	(SPI_OPM_RX_AS | SPI_OPM_RX_DOUT | \
+#define SPI_OPM_RX_AF		(1 << 1)
+#define SPI_OPM_RX_DOUT		(1 << 2)
+#define SPI_OPM_RX_DIO		(1 << 3)
+#define SPI_OPM_RX_QOF		(1 << 4)
+#define SPI_OPM_RX_QIOF		(1 << 5)
+#define SPI_OPM_RX_EXTN	(SPI_OPM_RX_AS | SPI_OPM_RX_AF | SPI_OPM_RX_DOUT | \
 				SPI_OPM_RX_DIO | SPI_OPM_RX_QOF | \
 				SPI_OPM_RX_DIO | SPI_OPM_RX_QOF | \
 				SPI_OPM_RX_QIOF)
 				SPI_OPM_RX_QIOF)
 
 
@@ -385,12 +386,12 @@ struct dm_spi_ops {
 	 * allowed to claim the same bus for several slaves without releasing
 	 * allowed to claim the same bus for several slaves without releasing
 	 * the bus in between.
 	 * the bus in between.
 	 *
 	 *
-	 * @bus:	The SPI slave
+	 * @dev:	The SPI slave
 	 *
 	 *
 	 * Returns: 0 if the bus was claimed successfully, or a negative value
 	 * Returns: 0 if the bus was claimed successfully, or a negative value
 	 * if it wasn't.
 	 * if it wasn't.
 	 */
 	 */
-	int (*claim_bus)(struct udevice *bus);
+	int (*claim_bus)(struct udevice *dev);
 
 
 	/**
 	/**
 	 * Release the SPI bus
 	 * Release the SPI bus
@@ -399,9 +400,9 @@ struct dm_spi_ops {
 	 * all transfers have finished. It may disable any SPI hardware as
 	 * all transfers have finished. It may disable any SPI hardware as
 	 * appropriate.
 	 * appropriate.
 	 *
 	 *
-	 * @bus:	The SPI slave
+	 * @dev:	The SPI slave
 	 */
 	 */
-	int (*release_bus)(struct udevice *bus);
+	int (*release_bus)(struct udevice *dev);
 
 
 	/**
 	/**
 	 * Set the word length for SPI transactions
 	 * Set the word length for SPI transactions
@@ -413,7 +414,7 @@ struct dm_spi_ops {
 	 *
 	 *
 	 * Returns: 0 on success, -ve on failure.
 	 * Returns: 0 on success, -ve on failure.
 	 */
 	 */
-	int (*set_wordlen)(struct udevice *bus, unsigned int wordlen);
+	int (*set_wordlen)(struct udevice *dev, unsigned int wordlen);
 
 
 	/**
 	/**
 	 * SPI transfer
 	 * SPI transfer

+ 4 - 5
include/spi_flash.h

@@ -62,11 +62,10 @@ struct spi_slave;
  * return 0 - Success, 1 - Failure
  * return 0 - Success, 1 - Failure
  */
  */
 struct spi_flash {
 struct spi_flash {
-#ifdef CONFIG_DM_SPI_FLASH
 	struct spi_slave *spi;
 	struct spi_slave *spi;
+#ifdef CONFIG_DM_SPI_FLASH
 	struct udevice *dev;
 	struct udevice *dev;
-#else
-	struct spi_slave *spi;
+	u16 flags;
 #endif
 #endif
 	const char *name;
 	const char *name;
 	u8 dual_flash;
 	u8 dual_flash;
@@ -91,13 +90,13 @@ struct spi_flash {
 #ifndef CONFIG_DM_SPI_FLASH
 #ifndef CONFIG_DM_SPI_FLASH
 	/*
 	/*
 	 * These are not strictly needed for driver model, but keep them here
 	 * These are not strictly needed for driver model, but keep them here
-	 * whilt the transition is in progress.
+	 * while the transition is in progress.
 	 *
 	 *
 	 * Normally each driver would provide its own operations, but for
 	 * Normally each driver would provide its own operations, but for
 	 * SPI flash most chips use the same algorithms. One approach is
 	 * SPI flash most chips use the same algorithms. One approach is
 	 * to create a 'common' SPI flash device which knows how to talk
 	 * to create a 'common' SPI flash device which knows how to talk
 	 * to most devices, and then allow other drivers to be used instead
 	 * to most devices, and then allow other drivers to be used instead
-	 * if requird, perhaps with a way of scanning through the list to
+	 * if required, perhaps with a way of scanning through the list to
 	 * find the driver that matches the device.
 	 * find the driver that matches the device.
 	 */
 	 */
 	int (*read)(struct spi_flash *flash, u32 offset, size_t len, void *buf);
 	int (*read)(struct spi_flash *flash, u32 offset, size_t len, void *buf);