Merge "ipq806x: spi: Enable 4K sector size support"
diff --git a/board/qca/arm/ipq807x/ipq807x.c b/board/qca/arm/ipq807x/ipq807x.c
index 52a3e50..250444f 100644
--- a/board/qca/arm/ipq807x/ipq807x.c
+++ b/board/qca/arm/ipq807x/ipq807x.c
@@ -425,7 +425,7 @@
 
 int board_mmc_init(bd_t *bis)
 {
-	int ret;
+	int ret = 0;
 	qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
 
 #ifndef CONFIG_SDHCI_SUPPORT
@@ -705,7 +705,8 @@
 	}
 	else if (index == 1) {
 		phybase = USB1_SSPHY_BASE;
-	}
+	} else
+		return;
 
 	out_8( phybase + USB3_PHY_POWER_DOWN_CONTROL,0x1);
 	out_8(phybase + QSERDES_COM_SYSCLK_EN_SEL,0x1a);
diff --git a/common/cmd_disk.c b/common/cmd_disk.c
index 8a1fda9..9dbe550 100644
--- a/common/cmd_disk.c
+++ b/common/cmd_disk.c
@@ -111,7 +111,7 @@
 #if defined(CONFIG_FIT)
 	/* This cannot be done earlier,
 	 * we need complete FIT image in RAM first */
-	if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) {
+	if (fit_hdr && genimg_get_format((void *)addr) == IMAGE_FORMAT_FIT) {
 		if (!fit_check_format(fit_hdr)) {
 			bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ);
 			puts("** Bad FIT image format\n");
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 190275d..c3e46d8 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -872,14 +872,14 @@
 
 #if defined(CONFIG_FIT)
 	/* This cannot be done earlier, we need complete FIT image in RAM first */
-	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) {
-		if (!fit_check_format (fit_hdr)) {
+	if (fit_hdr && genimg_get_format((void *)addr) == IMAGE_FORMAT_FIT) {
+		if (!fit_check_format(fit_hdr)) {
 			bootstage_error(BOOTSTAGE_ID_NAND_FIT_READ);
-			puts ("** Bad FIT image format\n");
+			puts("** Bad FIT image format\n");
 			return 1;
 		}
 		bootstage_mark(BOOTSTAGE_ID_NAND_FIT_READ_OK);
-		fit_print_contents (fit_hdr);
+		fit_print_contents(fit_hdr);
 	}
 #endif
 
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 03beb18..a38af31 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -79,21 +79,24 @@
 	uint32_t table_len = 0;
 
 	if (len <= SDHCI_ADMA_DESC_LINE_SZ) {
-		list = (struct adma_desc *) memalign(CACHE_LINE_SIZE, sizeof(struct adma_desc));
+		list = (struct adma_desc *)memalign(CACHE_LINE_SIZE,
+				sizeof(struct adma_desc));
 
 		if (!list) {
 			printf("Error allocating memory\n");
 			assert(0);
-		}
-
-		list[0].addr = (uint32_t)data;
-		list[0].len = (len < SDHCI_ADMA_DESC_LINE_SZ) ? len : (SDHCI_ADMA_DESC_LINE_SZ & 0xffff);
-		list[0].tran_att = SDHCI_ADMA_TRANS_VALID | SDHCI_ADMA_TRANS_DATA
-							  | SDHCI_ADMA_TRANS_END;
+		} else {
+			list[0].addr = (uint32_t)data;
+			list[0].len = (len < SDHCI_ADMA_DESC_LINE_SZ) ? len :
+				(SDHCI_ADMA_DESC_LINE_SZ & 0xffff);
+			list[0].tran_att = SDHCI_ADMA_TRANS_VALID |
+				SDHCI_ADMA_TRANS_DATA | SDHCI_ADMA_TRANS_END;
 
 #if !defined(CONFIG_SYS_DCACHE_OFF)
-		flush_cache((unsigned long)list, sizeof(struct adma_desc));
+			flush_cache((unsigned long)list,
+				    sizeof(struct adma_desc));
 #endif
+		}
 	} else {
 		list_len = len / SDHCI_ADMA_DESC_LINE_SZ;
 		remain = len - (list_len * SDHCI_ADMA_DESC_LINE_SZ);
@@ -108,26 +111,29 @@
 		if (!list) {
 			printf("Allocating memory failed\n");
 			assert(0);
-		}
+		} else {
+			memset((void *)list, 0, table_len);
 
-		memset((void *) list, 0, table_len);
-
-		for (i = 0; i < (list_len - 1); i++) {
+			for (i = 0; i < (list_len - 1); i++) {
 				list[i].addr = (uint32_t)data;
 				list[i].len = (SDHCI_ADMA_DESC_LINE_SZ & 0xffff);
-				list[i].tran_att = SDHCI_ADMA_TRANS_VALID | SDHCI_ADMA_TRANS_DATA;
+				list[i].tran_att = SDHCI_ADMA_TRANS_VALID |
+					SDHCI_ADMA_TRANS_DATA;
 				data += SDHCI_ADMA_DESC_LINE_SZ;
 				len -= SDHCI_ADMA_DESC_LINE_SZ;
 			}
 
 			list[list_len - 1].addr = (uint32_t)data;
-			list[list_len - 1].len = (len < SDHCI_ADMA_DESC_LINE_SZ) ? len : (SDHCI_ADMA_DESC_LINE_SZ & 0xffff);
-			list[list_len - 1].tran_att = SDHCI_ADMA_TRANS_VALID | SDHCI_ADMA_TRANS_DATA |
-										   SDHCI_ADMA_TRANS_END;
+			list[list_len - 1].len = (len < SDHCI_ADMA_DESC_LINE_SZ)
+				? len : (SDHCI_ADMA_DESC_LINE_SZ & 0xffff);
+			list[list_len - 1].tran_att = SDHCI_ADMA_TRANS_VALID |
+				SDHCI_ADMA_TRANS_DATA
+				| SDHCI_ADMA_TRANS_END;
 
 #if !defined(CONFIG_SYS_DCACHE_OFF)
-		flush_cache((unsigned long)list, table_len);
+			flush_cache((unsigned long)list, table_len);
 #endif
+		}
 	}
 
 
diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index ecc2b57..584814c 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -47,6 +47,7 @@
 	E_FSR		= 1 << 2,
 	SST_WR		= 1 << 3,
 	WR_QPP		= 1 << 4,
+	SECT_64K	= 1 << 5,
 };
 
 enum spi_nor_option_flags {
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 73c44fe..4f54af2 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -16,6 +16,7 @@
 #include <spi.h>
 #include <spi_flash.h>
 #include <linux/log2.h>
+#include <linux/sizes.h>
 
 #include "sf_internal.h"
 
@@ -370,6 +371,12 @@
 	}
 
 	cmd[0] = flash->erase_cmd;
+
+	if (!(offset % SZ_64K || len % SZ_64K) && (flash->flags & SECT_64K)) {
+		erase_size = SZ_64K;
+		cmd[0] = CMD_ERASE_64K;
+	}
+
 	while (len) {
 		erase_addr = offset;
 
@@ -1078,6 +1085,8 @@
 	if (params->flags & SECT_4K) {
 		flash->erase_cmd = CMD_ERASE_4K;
 		flash->erase_size = 4096 << flash->shift;
+		if (flash->sector_size == SZ_64K)
+			flash->flags |= SECT_64K;
 	} else if (params->flags & SECT_32K) {
 		flash->erase_cmd = CMD_ERASE_32K;
 		flash->erase_size = 32768 << flash->shift;
diff --git a/include/configs/ipq40xx.h b/include/configs/ipq40xx.h
index 7163a29..b4f84bc 100644
--- a/include/configs/ipq40xx.h
+++ b/include/configs/ipq40xx.h
@@ -223,6 +223,7 @@
 #define CONFIG_ENV_IS_IN_SPI_FLASH	1
 #define CONFIG_ENV_SECT_SIZE        	(64 * 1024)
 
+#define CONFIG_SPI_FLASH_USE_4K_SECTORS
 #define CONFIG_SF_DEFAULT_BUS 0
 #define CONFIG_SF_DEFAULT_CS 0
 #define CONFIG_SF_DEFAULT_MODE SPI_MODE_0