From ed4708aaeaf74008d199866bfbd450d91439a9cf Mon Sep 17 00:00:00 2001
From: Sumit Garg <sumit.garg@nxp.com>
Date: Wed, 25 May 2016 12:41:48 -0400
Subject: [PATCH 1/8] powerpc/board: SPL: Enable malloc flag in global data.

For malloc to work in SPL framework enable GD_FLG_FULL_MALLOC_INIT
flag in global data after allocating memory using mem_malloc_init.

Signed-off-by: Sumit Garg <sumit.garg@nxp.com>
Reviewed-by: York Sun <york.sun@nxp.com>
---
 board/freescale/b4860qds/spl.c     | 1 +
 board/freescale/c29xpcie/spl.c     | 1 +
 board/freescale/p1010rdb/spl.c     | 1 +
 board/freescale/p1022ds/spl.c      | 1 +
 board/freescale/p1_p2_rdb_pc/spl.c | 1 +
 board/freescale/t102xqds/spl.c     | 1 +
 board/freescale/t102xrdb/spl.c     | 1 +
 board/freescale/t104xrdb/spl.c     | 1 +
 board/freescale/t208xqds/spl.c     | 1 +
 board/freescale/t208xrdb/spl.c     | 1 +
 board/freescale/t4qds/spl.c        | 1 +
 board/freescale/t4rdb/spl.c        | 1 +
 12 files changed, 12 insertions(+)

diff --git a/board/freescale/b4860qds/spl.c b/board/freescale/b4860qds/spl.c
index 3f7cc03..fabc783 100644
--- a/board/freescale/b4860qds/spl.c
+++ b/board/freescale/b4860qds/spl.c
@@ -91,6 +91,7 @@ void board_init_r(gd_t *gd, ulong dest_addr)
 	get_clocks();
 	mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
 			CONFIG_SPL_RELOC_MALLOC_SIZE);
+	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 
 #ifndef CONFIG_SPL_NAND_BOOT
 	env_init();
diff --git a/board/freescale/c29xpcie/spl.c b/board/freescale/c29xpcie/spl.c
index 3d31d41..d8d73c7 100644
--- a/board/freescale/c29xpcie/spl.c
+++ b/board/freescale/c29xpcie/spl.c
@@ -57,6 +57,7 @@ void board_init_r(gd_t *gd, ulong dest_addr)
 	get_clocks();
 	mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
 			CONFIG_SPL_RELOC_MALLOC_SIZE);
+	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 
 	/* relocate environment function pointers etc. */
 	nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
diff --git a/board/freescale/p1010rdb/spl.c b/board/freescale/p1010rdb/spl.c
index eb8e567..f858408 100644
--- a/board/freescale/p1010rdb/spl.c
+++ b/board/freescale/p1010rdb/spl.c
@@ -72,6 +72,7 @@ void board_init_r(gd_t *gd, ulong dest_addr)
 	get_clocks();
 	mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
 			CONFIG_SPL_RELOC_MALLOC_SIZE);
+	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 
 #ifndef CONFIG_SPL_NAND_BOOT
 	env_init();
diff --git a/board/freescale/p1022ds/spl.c b/board/freescale/p1022ds/spl.c
index 89ef95a..04db767 100644
--- a/board/freescale/p1022ds/spl.c
+++ b/board/freescale/p1022ds/spl.c
@@ -86,6 +86,7 @@ void board_init_r(gd_t *gd, ulong dest_addr)
 	get_clocks();
 	mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
 			CONFIG_SPL_RELOC_MALLOC_SIZE);
+	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 #ifndef CONFIG_SPL_NAND_BOOT
 	env_init();
 #endif
diff --git a/board/freescale/p1_p2_rdb_pc/spl.c b/board/freescale/p1_p2_rdb_pc/spl.c
index 0142746..76a3cf4 100644
--- a/board/freescale/p1_p2_rdb_pc/spl.c
+++ b/board/freescale/p1_p2_rdb_pc/spl.c
@@ -83,6 +83,7 @@ void board_init_r(gd_t *gd, ulong dest_addr)
 	get_clocks();
 	mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
 			CONFIG_SPL_RELOC_MALLOC_SIZE);
+	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 
 #ifndef CONFIG_SPL_NAND_BOOT
 	env_init();
diff --git a/board/freescale/t102xqds/spl.c b/board/freescale/t102xqds/spl.c
index 073ff2d..d59d343 100644
--- a/board/freescale/t102xqds/spl.c
+++ b/board/freescale/t102xqds/spl.c
@@ -120,6 +120,7 @@ void board_init_r(gd_t *gd, ulong dest_addr)
 	get_clocks();
 	mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
 			CONFIG_SPL_RELOC_MALLOC_SIZE);
+	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 
 #ifdef CONFIG_SPL_NAND_BOOT
 	nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
diff --git a/board/freescale/t102xrdb/spl.c b/board/freescale/t102xrdb/spl.c
index da97c44..bd3cbbf 100644
--- a/board/freescale/t102xrdb/spl.c
+++ b/board/freescale/t102xrdb/spl.c
@@ -107,6 +107,7 @@ void board_init_r(gd_t *gd, ulong dest_addr)
 	get_clocks();
 	mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
 			CONFIG_SPL_RELOC_MALLOC_SIZE);
+	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 
 #ifdef CONFIG_SPL_NAND_BOOT
 	nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
diff --git a/board/freescale/t104xrdb/spl.c b/board/freescale/t104xrdb/spl.c
index 81f48c4..4b35af6 100644
--- a/board/freescale/t104xrdb/spl.c
+++ b/board/freescale/t104xrdb/spl.c
@@ -98,6 +98,7 @@ void board_init_r(gd_t *gd, ulong dest_addr)
 	get_clocks();
 	mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
 			CONFIG_SPL_RELOC_MALLOC_SIZE);
+	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 
 #ifdef CONFIG_SPL_MMC_BOOT
 	mmc_initialize(bd);
diff --git a/board/freescale/t208xqds/spl.c b/board/freescale/t208xqds/spl.c
index 55a0f8f..bb02dab 100644
--- a/board/freescale/t208xqds/spl.c
+++ b/board/freescale/t208xqds/spl.c
@@ -106,6 +106,7 @@ void board_init_r(gd_t *gd, ulong dest_addr)
 	get_clocks();
 	mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
 			CONFIG_SPL_RELOC_MALLOC_SIZE);
+	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 
 #ifdef CONFIG_SPL_NAND_BOOT
 	nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
diff --git a/board/freescale/t208xrdb/spl.c b/board/freescale/t208xrdb/spl.c
index f63366b..2ff05a2 100644
--- a/board/freescale/t208xrdb/spl.c
+++ b/board/freescale/t208xrdb/spl.c
@@ -76,6 +76,7 @@ void board_init_r(gd_t *gd, ulong dest_addr)
 	get_clocks();
 	mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
 			CONFIG_SPL_RELOC_MALLOC_SIZE);
+	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 
 #ifdef CONFIG_SPL_NAND_BOOT
 	nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
diff --git a/board/freescale/t4qds/spl.c b/board/freescale/t4qds/spl.c
index d52059a..6ca0f03 100644
--- a/board/freescale/t4qds/spl.c
+++ b/board/freescale/t4qds/spl.c
@@ -116,6 +116,7 @@ void board_init_r(gd_t *gd, ulong dest_addr)
 	get_clocks();
 	mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
 			CONFIG_SPL_RELOC_MALLOC_SIZE);
+	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 
 #ifdef CONFIG_SPL_NAND_BOOT
 	nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
diff --git a/board/freescale/t4rdb/spl.c b/board/freescale/t4rdb/spl.c
index 4c1e0cc..b148a7f 100644
--- a/board/freescale/t4rdb/spl.c
+++ b/board/freescale/t4rdb/spl.c
@@ -80,6 +80,7 @@ void board_init_r(gd_t *gd, ulong dest_addr)
 	get_clocks();
 	mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
 			CONFIG_SPL_RELOC_MALLOC_SIZE);
+	gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 
 	mmc_initialize(bd);
 	mmc_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,

From 534992827756c3a1ab49823ca487702a954fe433 Mon Sep 17 00:00:00 2001
From: Shengzhou Liu <Shengzhou.Liu@nxp.com>
Date: Tue, 31 May 2016 15:39:06 +0800
Subject: [PATCH 2/8] board/freescale: Use unified setup_ddr_tlbs for spl boot
 and non-spl boot

We should use unified setup_ddr_tlbs() for spl boot and non-spl boot
to make sure 'M' bit is set for DDR TLB to maintain cache coherence.

Signed-off-by: Shengzhou Liu <Shengzhou.Liu@nxp.com>
Reviewed-by: York Sun <york.sun@nxp.com>
---
 board/freescale/b4860qds/ddr.c | 8 +++-----
 board/freescale/t102xqds/ddr.c | 5 ++---
 board/freescale/t102xrdb/ddr.c | 4 ++--
 board/freescale/t104xrdb/ddr.c | 7 ++-----
 board/freescale/t208xqds/ddr.c | 5 ++---
 board/freescale/t208xrdb/ddr.c | 6 +++---
 board/freescale/t4qds/ddr.c    | 7 +++----
 board/freescale/t4rdb/ddr.c    | 5 ++---
 8 files changed, 19 insertions(+), 28 deletions(-)

diff --git a/board/freescale/b4860qds/ddr.c b/board/freescale/b4860qds/ddr.c
index eb10a6f..31b186e 100644
--- a/board/freescale/b4860qds/ddr.c
+++ b/board/freescale/b4860qds/ddr.c
@@ -179,15 +179,13 @@ phys_size_t initdram(int board_type)
 
 #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL)
 	puts("Initializing....using SPD\n");
-
 	dram_size = fsl_ddr_sdram();
-
-	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
-	dram_size *= 0x100000;
-
 #else
 	dram_size =  fsl_ddr_sdram_size();
 #endif
+	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
+	dram_size *= 0x100000;
+
 	return dram_size;
 }
 
diff --git a/board/freescale/t102xqds/ddr.c b/board/freescale/t102xqds/ddr.c
index 2d4d10f..fa1394d 100644
--- a/board/freescale/t102xqds/ddr.c
+++ b/board/freescale/t102xqds/ddr.c
@@ -172,14 +172,13 @@ phys_size_t initdram(int board_type)
 
 #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL)
 	puts("Initializing....using SPD\n");
-
 	dram_size = fsl_ddr_sdram();
-	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
-	dram_size *= 0x100000;
 #else
 	/* DDR has been initialised by first stage boot loader */
 	dram_size =  fsl_ddr_sdram_size();
 #endif
+	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
+	dram_size *= 0x100000;
 
 #if defined(CONFIG_DEEP_SLEEP) && !defined(CONFIG_SPL_BUILD)
 	fsl_dp_resume();
diff --git a/board/freescale/t102xrdb/ddr.c b/board/freescale/t102xrdb/ddr.c
index adf9fd5..b13692b 100644
--- a/board/freescale/t102xrdb/ddr.c
+++ b/board/freescale/t102xrdb/ddr.c
@@ -234,12 +234,12 @@ phys_size_t initdram(int board_type)
 	puts("Initializing....using SPD\n");
 #endif
 	dram_size = fsl_ddr_sdram();
-	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
-	dram_size *= 0x100000;
 #else
 	/* DDR has been initialised by first stage boot loader */
 	dram_size =  fsl_ddr_sdram_size();
 #endif
+	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
+	dram_size *= 0x100000;
 
 #if defined(CONFIG_DEEP_SLEEP) && !defined(CONFIG_SPL_BUILD)
 	fsl_dp_resume();
diff --git a/board/freescale/t104xrdb/ddr.c b/board/freescale/t104xrdb/ddr.c
index cf79d2d..22d6a5f 100644
--- a/board/freescale/t104xrdb/ddr.c
+++ b/board/freescale/t104xrdb/ddr.c
@@ -124,15 +124,12 @@ phys_size_t initdram(int board_type)
 
 #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL)
 	puts("Initializing....using SPD\n");
-
 	dram_size = fsl_ddr_sdram();
-
-	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
-	dram_size *= 0x100000;
-
 #else
 	dram_size =  fsl_ddr_sdram_size();
 #endif
+	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
+	dram_size *= 0x100000;
 
 #if defined(CONFIG_DEEP_SLEEP) && !defined(CONFIG_SPL_BUILD)
 	fsl_dp_resume();
diff --git a/board/freescale/t208xqds/ddr.c b/board/freescale/t208xqds/ddr.c
index f1aff54..f96470f 100644
--- a/board/freescale/t208xqds/ddr.c
+++ b/board/freescale/t208xqds/ddr.c
@@ -108,13 +108,12 @@ phys_size_t initdram(int board_type)
 #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL)
 	puts("Initializing....using SPD\n");
 	dram_size = fsl_ddr_sdram();
-
-	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
-	dram_size *= 0x100000;
 #else
 	/* DDR has been initialised by first stage boot loader */
 	dram_size =  fsl_ddr_sdram_size();
 #endif
+	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
+	dram_size *= 0x100000;
 
 	return dram_size;
 }
diff --git a/board/freescale/t208xrdb/ddr.c b/board/freescale/t208xrdb/ddr.c
index 053f128..f6c8ca3 100644
--- a/board/freescale/t208xrdb/ddr.c
+++ b/board/freescale/t208xrdb/ddr.c
@@ -101,12 +101,12 @@ phys_size_t initdram(int board_type)
 #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL)
 	puts("Initializing....using SPD\n");
 	dram_size = fsl_ddr_sdram();
-
-	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
-	dram_size *= 0x100000;
 #else
 	/* DDR has been initialised by first stage boot loader */
 	dram_size = fsl_ddr_sdram_size();
 #endif
+	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
+	dram_size *= 0x100000;
+
 	return dram_size;
 }
diff --git a/board/freescale/t4qds/ddr.c b/board/freescale/t4qds/ddr.c
index 62d58c5..d533924 100644
--- a/board/freescale/t4qds/ddr.c
+++ b/board/freescale/t4qds/ddr.c
@@ -117,13 +117,12 @@ phys_size_t initdram(int board_type)
 
 #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL)
 	dram_size = fsl_ddr_sdram();
-
-	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
-	dram_size *= 0x100000;
-
 #else
 	/* DDR has been initialised by first stage boot loader */
 	dram_size = fsl_ddr_sdram_size();
 #endif
+	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
+	dram_size *= 0x100000;
+
 	return dram_size;
 }
diff --git a/board/freescale/t4rdb/ddr.c b/board/freescale/t4rdb/ddr.c
index 27b37b5..230f031 100644
--- a/board/freescale/t4rdb/ddr.c
+++ b/board/freescale/t4rdb/ddr.c
@@ -110,13 +110,12 @@ phys_size_t initdram(int board_type)
 
 #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL)
 	dram_size = fsl_ddr_sdram();
-
-	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
-	dram_size *= 0x100000;
 #else
 	/* DDR has been initialised by first stage boot loader */
 	dram_size = fsl_ddr_sdram_size();
 #endif
+	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
+	dram_size *= 0x100000;
 
 	return dram_size;
 }

From b7707b043ebbf88fe0fb49442db9316ded3a0740 Mon Sep 17 00:00:00 2001
From: "Robert P. J. Day" <rpjday@crashcourse.ca>
Date: Mon, 23 May 2016 06:49:21 -0400
Subject: [PATCH 3/8] arch/powerpc: Simplify some calculations using
 ARRAY_SIZE() macro.

Replace a number of array length calculations with the ARRAY_SIZE()
macro, for clarity.

Signed-off-by: Robert P. J. Day <rpjday@crashcourse.ca>
Reviewed-by: York Sun <york.sun@nxp.com>
---
 arch/powerpc/cpu/mpc512x/fixed_sdram.c | 2 +-
 arch/powerpc/cpu/mpc8260/cpu_init.c    | 2 +-
 arch/powerpc/cpu/mpc8260/ether_fcc.c   | 8 ++++----
 arch/powerpc/cpu/mpc83xx/cpu_init.c    | 2 +-
 arch/powerpc/cpu/mpc83xx/speed.c       | 2 +-
 arch/powerpc/cpu/mpc85xx/ether_fcc.c   | 2 +-
 arch/powerpc/cpu/mpc8xx/fec.c          | 4 ++--
 arch/powerpc/cpu/ppc4xx/reginfo.c      | 2 +-
 arch/powerpc/cpu/ppc4xx/sdram.c        | 4 ++--
 9 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/cpu/mpc512x/fixed_sdram.c b/arch/powerpc/cpu/mpc512x/fixed_sdram.c
index 6451ea9..68c5f8a 100644
--- a/arch/powerpc/cpu/mpc512x/fixed_sdram.c
+++ b/arch/powerpc/cpu/mpc512x/fixed_sdram.c
@@ -70,7 +70,7 @@ long int fixed_sdram(ddr512x_config_t *mddrc_config,
 		mddrc_config = &default_mddrc_config;
 	if (dram_init_seq == NULL) {
 		dram_init_seq = default_init_seq;
-		seq_sz = sizeof(default_init_seq)/sizeof(u32);
+		seq_sz = ARRAY_SIZE(default_init_seq);
 	}
 
 	/* Initialize IO Control */
diff --git a/arch/powerpc/cpu/mpc8260/cpu_init.c b/arch/powerpc/cpu/mpc8260/cpu_init.c
index a9bb5ad..55130f7 100644
--- a/arch/powerpc/cpu/mpc8260/cpu_init.c
+++ b/arch/powerpc/cpu/mpc8260/cpu_init.c
@@ -253,7 +253,7 @@ int prt_8260_rsr (void)
 		RSR_ESRS, "External Soft"}, {
 		RSR_EHRS, "External Hard"}
 	};
-	static int n = sizeof bits / sizeof bits[0];
+	static int n = ARRAY_SIZE(bits);
 	ulong rsr = gd->arch.reset_status;
 	int i;
 	char *sep;
diff --git a/arch/powerpc/cpu/mpc8260/ether_fcc.c b/arch/powerpc/cpu/mpc8260/ether_fcc.c
index 9bb395e..a11ad1e 100644
--- a/arch/powerpc/cpu/mpc8260/ether_fcc.c
+++ b/arch/powerpc/cpu/mpc8260/ether_fcc.c
@@ -362,7 +362,7 @@ int fec_initialize(bd_t *bis)
 	struct eth_device* dev;
 	int i;
 
-	for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++)
+	for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++)
 	{
 		dev = (struct eth_device*) malloc(sizeof *dev);
 		memset(dev, 0, sizeof *dev);
@@ -432,7 +432,7 @@ static elbt_prdesc rxeacc_descs[] = {
 	{ offsetof(elbt_rxeacc, badlen),	"Bad Frame Length"	},
 	{ offsetof(elbt_rxeacc, badbit),	"Data Compare Errors"	},
 };
-static int rxeacc_ndesc = sizeof (rxeacc_descs) / sizeof (rxeacc_descs[0]);
+static int rxeacc_ndesc = ARRAY_SIZE(rxeacc_descs);
 
 typedef
 	struct {
@@ -449,7 +449,7 @@ static elbt_prdesc txeacc_descs[] = {
 	{ offsetof(elbt_txeacc, un),		"Underrun"		},
 	{ offsetof(elbt_txeacc, csl),		"Carrier Sense Lost"	},
 };
-static int txeacc_ndesc = sizeof (txeacc_descs) / sizeof (txeacc_descs[0]);
+static int txeacc_ndesc = ARRAY_SIZE(txeacc_descs);
 
 typedef
 	struct {
@@ -500,7 +500,7 @@ static elbt_prdesc epram_descs[] = {
 	{ offsetof(fcc_enet_t, fen_p512c),	"512-1023 Octet Frames"	},
 	{ offsetof(fcc_enet_t, fen_p1024c),	"1024-1518 Octet Frames"},
 };
-static int epram_ndesc = sizeof (epram_descs) / sizeof (epram_descs[0]);
+static int epram_ndesc = ARRAY_SIZE(epram_descs);
 
 /*
  * given an elbt_prdesc array and an array of base addresses, print
diff --git a/arch/powerpc/cpu/mpc83xx/cpu_init.c b/arch/powerpc/cpu/mpc83xx/cpu_init.c
index 0791043..f911275 100644
--- a/arch/powerpc/cpu/mpc83xx/cpu_init.c
+++ b/arch/powerpc/cpu/mpc83xx/cpu_init.c
@@ -484,7 +484,7 @@ int prt_83xx_rsr(void)
 		RSR_SRS,  "External/Internal Soft"}, {
 		RSR_HRS,  "External/Internal Hard"}
 	};
-	static int n = sizeof bits / sizeof bits[0];
+	static int n = ARRAY_SIZE(bits);
 	ulong rsr = gd->arch.reset_status;
 	int i;
 	char *sep;
diff --git a/arch/powerpc/cpu/mpc83xx/speed.c b/arch/powerpc/cpu/mpc83xx/speed.c
index 2e91f51..5498c19 100644
--- a/arch/powerpc/cpu/mpc83xx/speed.c
+++ b/arch/powerpc/cpu/mpc83xx/speed.c
@@ -412,7 +412,7 @@ int get_clocks(void)
 #endif
 
 	corecnf_tab_index = ((corepll & 0x1F) << 2) | ((corepll & 0x60) >> 5);
-	if (corecnf_tab_index > (sizeof(corecnf_tab) / sizeof(corecnf_t))) {
+	if (corecnf_tab_index > (ARRAY_SIZE(corecnf_tab))) {
 		/* corecnf_tab_index is too high, possibly wrong value */
 		return -11;
 	}
diff --git a/arch/powerpc/cpu/mpc85xx/ether_fcc.c b/arch/powerpc/cpu/mpc85xx/ether_fcc.c
index 14358ae..51f1bee 100644
--- a/arch/powerpc/cpu/mpc85xx/ether_fcc.c
+++ b/arch/powerpc/cpu/mpc85xx/ether_fcc.c
@@ -424,7 +424,7 @@ int fec_initialize(bd_t *bis)
 	struct eth_device* dev;
 	int i;
 
-	for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++)
+	for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++)
 	{
 		dev = (struct eth_device*) malloc(sizeof *dev);
 		memset(dev, 0, sizeof *dev);
diff --git a/arch/powerpc/cpu/mpc8xx/fec.c b/arch/powerpc/cpu/mpc8xx/fec.c
index ea4ab3a..f1ae358 100644
--- a/arch/powerpc/cpu/mpc8xx/fec.c
+++ b/arch/powerpc/cpu/mpc8xx/fec.c
@@ -137,7 +137,7 @@ int fec_initialize(bd_t *bis)
 	struct ether_fcc_info_s *efis;
 	int             i;
 
-	for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++) {
+	for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++) {
 
 		dev = malloc(sizeof(*dev));
 		if (dev == NULL)
@@ -879,7 +879,7 @@ void mii_init (void)
 
 	/* Setup the pin configuration of the FEC(s)
 	*/
-	for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++)
+	for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++)
 		fec_pin_init(ether_fcc_info[i].ether_index);
 }
 
diff --git a/arch/powerpc/cpu/ppc4xx/reginfo.c b/arch/powerpc/cpu/ppc4xx/reginfo.c
index 339d38a..a42327e 100644
--- a/arch/powerpc/cpu/ppc4xx/reginfo.c
+++ b/arch/powerpc/cpu/ppc4xx/reginfo.c
@@ -321,7 +321,7 @@ void ppc4xx_reginfo(void)
 	PRINT_DCR(OPB2PLB40_BCTRL);
 	PRINT_DCR(P4P3BO0_CFG);
 #endif
-	n = sizeof(ppc4xx_reg) / sizeof(ppc4xx_reg[0]);
+	n = ARRAY_SIZE(ppc4xx_reg);
 	for (i = 0; i < n; i++) {
 		value = 0;
 		type = ppc4xx_reg[i].type;
diff --git a/arch/powerpc/cpu/ppc4xx/sdram.c b/arch/powerpc/cpu/ppc4xx/sdram.c
index d4ef36d..cd63456 100644
--- a/arch/powerpc/cpu/ppc4xx/sdram.c
+++ b/arch/powerpc/cpu/ppc4xx/sdram.c
@@ -33,7 +33,7 @@ sdram_conf_t mb0cf[] = {
 sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
 #endif
 
-#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
+#define N_MB0CF (ARRAY_SIZE(mb0cf))
 
 #ifdef CONFIG_SYS_SDRAM_CASL
 static ulong ns2clks(ulong ns)
@@ -266,7 +266,7 @@ sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
 #define CONFIG_SYS_SDRAM0_CFG0		0x82000000 /* DCEN=1, PMUD=0, 64-bit */
 #endif
 
-#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
+#define N_MB0CF (ARRAY_SIZE(mb0cf))
 
 #define NUM_TRIES 64
 #define NUM_READS 10

From 07d31f8f98fb350776c78a681ef27fd8ee288acd Mon Sep 17 00:00:00 2001
From: "mario.six@gdsys.cc" <mario.six@gdsys.cc>
Date: Wed, 25 May 2016 15:15:20 +0200
Subject: [PATCH 4/8] dm: gpio: Add driver for MPC85XX GPIO controller

This patch adds a driver for the built-in GPIO controller of the MPC85XX
SoC (probably supporting other PowerQUICC III SoCs as well).

Each GPIO bank is identified by its own entry in the device tree, i.e.

gpio-controller@fc00 {
      #gpio-cells = <2>;
      compatible = "fsl,pq3-gpio";
      reg = <0xfc00 0x100>
}

By default, each bank is assumed to have 32 GPIOs, but the ngpios
setting is honored, so the number of GPIOs for each bank in configurable
to match the actual GPIO count of the SoC (e.g. the 32/32/23 banks of
the P1022 SoC).

The usual functions of GPIO drivers (setting input/output mode and output
value setting) are supported.

The driver has been tested on MPC85XX, but it is likely that other
PowerQUICC III devices will work as well.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: York Sun <york.sun@nxp.com>
---
 arch/powerpc/include/asm/arch-mpc85xx/gpio.h |   2 +
 arch/powerpc/include/asm/immap_85xx.h        |   2 +
 drivers/gpio/Kconfig                         |  26 ++++
 drivers/gpio/Makefile                        |   1 +
 drivers/gpio/mpc85xx_gpio.c                  | 187 +++++++++++++++++++++++++++
 5 files changed, 218 insertions(+)
 create mode 100644 drivers/gpio/mpc85xx_gpio.c

diff --git a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
index da7352a..41b6677 100644
--- a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
+++ b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
@@ -14,6 +14,8 @@
 #ifndef __ASM_ARCH_MX85XX_GPIO_H
 #define __ASM_ARCH_MX85XX_GPIO_H
 
+#ifndef CONFIG_MPC85XX_GPIO
 #include <asm/mpc85xx_gpio.h>
+#endif
 
 #endif
diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h
index 07d2adf..c045a24 100644
--- a/arch/powerpc/include/asm/immap_85xx.h
+++ b/arch/powerpc/include/asm/immap_85xx.h
@@ -265,6 +265,7 @@ typedef struct ccsr_pcix {
 #define PIWAR_WRITE_SNOOP	0x00005000
 #define PIWAR_MEM_2G		0x0000001e
 
+#ifndef CONFIG_MPC85XX_GPIO
 typedef struct ccsr_gpio {
 	u32	gpdir;
 	u32	gpodr;
@@ -273,6 +274,7 @@ typedef struct ccsr_gpio {
 	u32	gpimr;
 	u32	gpicr;
 } ccsr_gpio_t;
+#endif
 
 /* L2 Cache Registers */
 typedef struct ccsr_l2cache {
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 93a7e8c..b674a47 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -173,4 +173,30 @@ config DM_PCA953X
 
 	  Now, max 24 bits chips and PCA953X compatible chips are
 	  supported
+
+config MPC85XX_GPIO
+	bool "Freescale MPC85XX GPIO driver"
+	depends on DM_GPIO
+	help
+	  This driver supports the built-in GPIO controller of MPC85XX CPUs.
+	  Each GPIO bank is identified by its own entry in the device tree,
+	  i.e.
+
+	  gpio-controller@fc00 {
+		#gpio-cells = <2>;
+		compatible = "fsl,pq3-gpio";
+		reg = <0xfc00 0x100>
+	  }
+
+	  By default, each bank is assumed to have 32 GPIOs, but the ngpios
+	  setting is honored, so the number of GPIOs for each bank is
+	  configurable to match the actual GPIO count of the SoC (e.g. the
+	  32/32/23 banks of the P1022 SoC).
+
+	  The standard functions of input/output mode, and output value setting
+	  are supported; the open-drain capability of the controller is not
+	  supported yet.
+
+	  The driver has been tested on MPC85XX, but it is likely that other
+	  PowerQUICC III devices will work as well.
 endmenu
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index ddec1ef..21b2cc2 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_DA8XX_GPIO)	+= da8xx_gpio.o
 obj-$(CONFIG_DM644X_GPIO)	+= da8xx_gpio.o
 obj-$(CONFIG_ALTERA_PIO)	+= altera_pio.o
 obj-$(CONFIG_MPC83XX_GPIO)	+= mpc83xx_gpio.o
+obj-$(CONFIG_MPC85XX_GPIO)	+= mpc85xx_gpio.o
 obj-$(CONFIG_SH_GPIO_PFC)	+= sh_pfc.o
 obj-$(CONFIG_OMAP_GPIO)	+= omap_gpio.o
 obj-$(CONFIG_DB8500_GPIO)	+= db8500_gpio.o
diff --git a/drivers/gpio/mpc85xx_gpio.c b/drivers/gpio/mpc85xx_gpio.c
new file mode 100644
index 0000000..17755df
--- /dev/null
+++ b/drivers/gpio/mpc85xx_gpio.c
@@ -0,0 +1,187 @@
+/*
+ * (C) Copyright 2016
+ * Mario Six, Guntermann & Drunck GmbH, six@gdsys.de
+ *
+ * based on arch/powerpc/include/asm/mpc85xx_gpio.h, which is
+ *
+ * Copyright 2010 eXMeritus, A Boeing Company
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/gpio.h>
+#include <mapmem.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct ccsr_gpio {
+	u32	gpdir;
+	u32	gpodr;
+	u32	gpdat;
+	u32	gpier;
+	u32	gpimr;
+	u32	gpicr;
+};
+
+struct mpc85xx_gpio_data {
+	/* The bank's register base in memory */
+	struct ccsr_gpio __iomem *base;
+	/* The address of the registers; used to identify the bank */
+	ulong addr;
+	/* The GPIO count of the bank */
+	uint gpio_count;
+	/* The GPDAT register cannot be used to determine the value of output
+	 * pins on MPC8572/MPC8536, so we shadow it and use the shadowed value
+	 * for output pins */
+	u32 dat_shadow;
+};
+
+inline u32 gpio_mask(unsigned gpio) {
+	return (1U << (31 - (gpio)));
+}
+
+static inline u32 mpc85xx_gpio_get_val(struct ccsr_gpio *base, u32 mask)
+{
+	return in_be32(&base->gpdat) & mask;
+}
+
+static inline u32 mpc85xx_gpio_get_dir(struct ccsr_gpio *base, u32 mask)
+{
+	return in_be32(&base->gpdir) & mask;
+}
+
+static inline void mpc85xx_gpio_set_in(struct ccsr_gpio *base, u32 gpios)
+{
+	clrbits_be32(&base->gpdat, gpios);
+	/* GPDIR register 0 -> input */
+	clrbits_be32(&base->gpdir, gpios);
+}
+
+static inline void mpc85xx_gpio_set_low(struct ccsr_gpio *base, u32 gpios)
+{
+	clrbits_be32(&base->gpdat, gpios);
+	/* GPDIR register 1 -> output */
+	setbits_be32(&base->gpdir, gpios);
+}
+
+static inline void mpc85xx_gpio_set_high(struct ccsr_gpio *base, u32 gpios)
+{
+	setbits_be32(&base->gpdat, gpios);
+	/* GPDIR register 1 -> output */
+	setbits_be32(&base->gpdir, gpios);
+}
+
+static int mpc85xx_gpio_direction_input(struct udevice *dev, unsigned gpio)
+{
+	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
+
+	mpc85xx_gpio_set_in(data->base, gpio_mask(gpio));
+	return 0;
+}
+
+static int mpc85xx_gpio_set_value(struct udevice *dev, unsigned gpio,
+				  int value)
+{
+	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
+
+	if (value) {
+		data->dat_shadow |= gpio_mask(gpio);
+		mpc85xx_gpio_set_high(data->base, gpio_mask(gpio));
+	} else {
+		data->dat_shadow &= ~gpio_mask(gpio);
+		mpc85xx_gpio_set_low(data->base, gpio_mask(gpio));
+	}
+	return 0;
+}
+
+static int mpc85xx_gpio_direction_output(struct udevice *dev, unsigned gpio,
+					 int value)
+{
+	return mpc85xx_gpio_set_value(dev, gpio, value);
+}
+
+static int mpc85xx_gpio_get_value(struct udevice *dev, unsigned gpio)
+{
+	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
+
+	if (!!mpc85xx_gpio_get_dir(data->base, gpio_mask(gpio))) {
+		/* Output -> use shadowed value */
+		return !!(data->dat_shadow & gpio_mask(gpio));
+	} else {
+		/* Input -> read value from GPDAT register */
+		return !!mpc85xx_gpio_get_val(data->base, gpio_mask(gpio));
+	}
+}
+
+static int mpc85xx_gpio_get_function(struct udevice *dev, unsigned gpio)
+{
+	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
+	int dir;
+
+	dir = !!mpc85xx_gpio_get_dir(data->base, gpio_mask(gpio));
+	return dir ? GPIOF_OUTPUT : GPIOF_INPUT;
+}
+
+static int mpc85xx_gpio_ofdata_to_platdata(struct udevice *dev) {
+	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
+	fdt_addr_t addr;
+	fdt_size_t size;
+
+	addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev->of_offset,
+						  "reg", 0, &size);
+
+	data->addr = addr;
+	data->base = map_sysmem(CONFIG_SYS_IMMR + addr, size);
+
+	if (!data->base)
+		return -ENOMEM;
+
+	data->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+					  "ngpios", 32);
+	data->dat_shadow = 0;
+
+	return 0;
+}
+
+static int mpc85xx_gpio_probe(struct udevice *dev)
+{
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
+	char name[32], *str;
+
+	snprintf(name, sizeof(name), "MPC@%lx_", data->addr);
+	str = strdup(name);
+
+	if (!str)
+		return -ENOMEM;
+
+	uc_priv->bank_name = str;
+	uc_priv->gpio_count = data->gpio_count;
+
+	return 0;
+}
+
+static const struct dm_gpio_ops gpio_mpc85xx_ops = {
+	.direction_input	= mpc85xx_gpio_direction_input,
+	.direction_output	= mpc85xx_gpio_direction_output,
+	.get_value		= mpc85xx_gpio_get_value,
+	.set_value		= mpc85xx_gpio_set_value,
+	.get_function 		= mpc85xx_gpio_get_function,
+};
+
+static const struct udevice_id mpc85xx_gpio_ids[] = {
+	{ .compatible = "fsl,pq3-gpio" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(gpio_mpc85xx) = {
+	.name	= "gpio_mpc85xx",
+	.id	= UCLASS_GPIO,
+	.ops	= &gpio_mpc85xx_ops,
+	.ofdata_to_platdata = mpc85xx_gpio_ofdata_to_platdata,
+	.of_match = mpc85xx_gpio_ids,
+	.probe	= mpc85xx_gpio_probe,
+	.priv_auto_alloc_size = sizeof(struct mpc85xx_gpio_data),
+};

From 53ecdfb92034ce836ec94ba33ba0d8d27ea3c16c Mon Sep 17 00:00:00 2001
From: "mario.six@gdsys.cc" <mario.six@gdsys.cc>
Date: Wed, 25 May 2016 15:15:21 +0200
Subject: [PATCH 5/8] dm: gpio: Add methods for open drain setting

Certain GPIO devices have the capability to switch their GPIOs into
open-drain mode, that is, instead of actively driving the output
(Push-pull output), the pin is connected to the collector (for a NPN
transistor) or the drain (for a MOSFET) of a transistor, respectively.
The pin then either forms an open circuit or a connection to ground,
depending on the state of the transistor.

This patch adds functions to the GPIO uclass to switch GPIOs to
open-drain mode on devices that support it.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: York Sun <york.sun@nxp.com>
---
 drivers/gpio/gpio-uclass.c | 32 ++++++++++++++++++++++++++++++++
 include/asm-generic/gpio.h | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 732b6c2..4559739 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -367,6 +367,38 @@ int dm_gpio_set_value(const struct gpio_desc *desc, int value)
 	return 0;
 }
 
+int dm_gpio_get_open_drain(struct gpio_desc *desc)
+{
+	struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
+	int ret;
+
+	ret = check_reserved(desc, "get_open_drain");
+	if (ret)
+		return ret;
+
+	if (ops->set_open_drain)
+		return ops->get_open_drain(desc->dev, desc->offset);
+	else
+		return -ENOSYS;
+}
+
+int dm_gpio_set_open_drain(struct gpio_desc *desc, int value)
+{
+	struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
+	int ret;
+
+	ret = check_reserved(desc, "set_open_drain");
+	if (ret)
+		return ret;
+
+	if (ops->set_open_drain)
+		ret = ops->set_open_drain(desc->dev, desc->offset, value);
+	else
+		return 0; /* feature not supported -> ignore setting */
+
+	return ret;
+}
+
 int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
 {
 	struct udevice *dev = desc->dev;
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 2500c10..4aa0004 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -251,6 +251,8 @@ struct dm_gpio_ops {
 				int value);
 	int (*get_value)(struct udevice *dev, unsigned offset);
 	int (*set_value)(struct udevice *dev, unsigned offset, int value);
+	int (*get_open_drain)(struct udevice *dev, unsigned offset);
+	int (*set_open_drain)(struct udevice *dev, unsigned offset, int value);
 	/**
 	 * get_function() Get the GPIO function
 	 *
@@ -550,6 +552,38 @@ int dm_gpio_get_value(const struct gpio_desc *desc);
 int dm_gpio_set_value(const struct gpio_desc *desc, int value);
 
 /**
+ * dm_gpio_get_open_drain() - Check if open-drain-mode of a GPIO is active
+ *
+ * This checks if open-drain-mode for a GPIO is enabled or not. This method is
+ * optional.
+ *
+ * @desc:	GPIO description containing device, offset and flags,
+ *		previously returned by gpio_request_by_name()
+ * @return Value of open drain mode for GPIO (0 for inactive, 1 for active) or
+ *	   -ve on error
+ */
+int dm_gpio_get_open_drain(struct gpio_desc *desc);
+
+/**
+ * dm_gpio_set_open_drain() - Switch open-drain-mode of a GPIO on or off
+ *
+ * This enables or disables open-drain mode for a GPIO. This method is
+ * optional; if the driver does not support it, nothing happens when the method
+ * is called.
+ *
+ * In open-drain mode, instead of actively driving the output (Push-pull
+ * output), the GPIO's pin is connected to the collector (for a NPN transistor)
+ * or the drain (for a MOSFET) of a transistor, respectively. The pin then
+ * either forms an open circuit or a connection to ground, depending on the
+ * state of the transistor.
+ *
+ * @desc:	GPIO description containing device, offset and flags,
+ *		previously returned by gpio_request_by_name()
+ * @return 0 if OK, -ve on error
+ */
+int dm_gpio_set_open_drain(struct gpio_desc *desc, int value);
+
+/**
  * dm_gpio_set_dir() - Set the direction for a GPIO
  *
  * This sets up the direction according tot the provided flags. It will do

From 51781783c59ad0080621d777579eb8acd14aa0ed Mon Sep 17 00:00:00 2001
From: "mario.six@gdsys.cc" <mario.six@gdsys.cc>
Date: Wed, 25 May 2016 15:15:22 +0200
Subject: [PATCH 6/8] dm: gpio: Implement open drain for MPC85XX GPIO

This patch implements the open-drain setting feature for the MPC85XX
GPIO controller.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: York Sun <york.sun@nxp.com>
---
 drivers/gpio/Kconfig        |  6 +++---
 drivers/gpio/mpc85xx_gpio.c | 41 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b674a47..8595e2e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -193,9 +193,9 @@ config MPC85XX_GPIO
 	  configurable to match the actual GPIO count of the SoC (e.g. the
 	  32/32/23 banks of the P1022 SoC).
 
-	  The standard functions of input/output mode, and output value setting
-	  are supported; the open-drain capability of the controller is not
-	  supported yet.
+	  Aside from the standard functions of input/output mode, and output
+	  value setting, the open-drain feature, which can configure individual
+	  GPIOs to work as open-drain outputs, is supported.
 
 	  The driver has been tested on MPC85XX, but it is likely that other
 	  PowerQUICC III devices will work as well.
diff --git a/drivers/gpio/mpc85xx_gpio.c b/drivers/gpio/mpc85xx_gpio.c
index 17755df..04773e2 100644
--- a/drivers/gpio/mpc85xx_gpio.c
+++ b/drivers/gpio/mpc85xx_gpio.c
@@ -73,6 +73,25 @@ static inline void mpc85xx_gpio_set_high(struct ccsr_gpio *base, u32 gpios)
 	setbits_be32(&base->gpdir, gpios);
 }
 
+static inline int mpc85xx_gpio_open_drain_val(struct ccsr_gpio *base, u32 mask)
+{
+	return in_be32(&base->gpodr) & mask;
+}
+
+static inline void mpc85xx_gpio_open_drain_on(struct ccsr_gpio *base, u32
+					      gpios)
+{
+	/* GPODR register 1 -> open drain on */
+	setbits_be32(&base->gpodr, gpios);
+}
+
+static inline void mpc85xx_gpio_open_drain_off(struct ccsr_gpio *base,
+					       u32 gpios)
+{
+	/* GPODR register 0 -> open drain off (actively driven) */
+	clrbits_be32(&base->gpodr, gpios);
+}
+
 static int mpc85xx_gpio_direction_input(struct udevice *dev, unsigned gpio)
 {
 	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
@@ -115,6 +134,26 @@ static int mpc85xx_gpio_get_value(struct udevice *dev, unsigned gpio)
 	}
 }
 
+static int mpc85xx_gpio_get_open_drain(struct udevice *dev, unsigned gpio)
+{
+	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
+
+	return !!mpc85xx_gpio_open_drain_val(data->base, gpio_mask(gpio));
+}
+
+static int mpc85xx_gpio_set_open_drain(struct udevice *dev, unsigned gpio,
+				       int value)
+{
+	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
+
+	if (value) {
+		mpc85xx_gpio_open_drain_on(data->base, gpio_mask(gpio));
+	} else {
+		mpc85xx_gpio_open_drain_off(data->base, gpio_mask(gpio));
+	}
+	return 0;
+}
+
 static int mpc85xx_gpio_get_function(struct udevice *dev, unsigned gpio)
 {
 	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
@@ -168,6 +207,8 @@ static const struct dm_gpio_ops gpio_mpc85xx_ops = {
 	.direction_output	= mpc85xx_gpio_direction_output,
 	.get_value		= mpc85xx_gpio_get_value,
 	.set_value		= mpc85xx_gpio_set_value,
+	.get_open_drain		= mpc85xx_gpio_get_open_drain,
+	.set_open_drain		= mpc85xx_gpio_set_open_drain,
 	.get_function 		= mpc85xx_gpio_get_function,
 };
 

From 743268f5146e3fd93abb8b6142ef6a259a0656c5 Mon Sep 17 00:00:00 2001
From: "mario.six@gdsys.cc" <mario.six@gdsys.cc>
Date: Wed, 25 May 2016 15:15:23 +0200
Subject: [PATCH 7/8] dm: test: Add GPIO open drain tests

Add some tests for the new open drain setting feature of the GPIO
uclass, and extend the capabilities of the sandbox GPIO driver
accordingly.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: York Sun <york.sun@nxp.com>
---
 arch/sandbox/include/asm/gpio.h | 20 ++++++++++++++++++++
 drivers/gpio/sandbox.c          | 35 +++++++++++++++++++++++++++++++++++
 test/dm/gpio.c                  |  7 +++++++
 3 files changed, 62 insertions(+)

diff --git a/arch/sandbox/include/asm/gpio.h b/arch/sandbox/include/asm/gpio.h
index 8317db1..427af2c 100644
--- a/arch/sandbox/include/asm/gpio.h
+++ b/arch/sandbox/include/asm/gpio.h
@@ -41,6 +41,26 @@ int sandbox_gpio_get_value(struct udevice *dev, unsigned int offset);
 int sandbox_gpio_set_value(struct udevice *dev, unsigned int offset, int value);
 
 /**
+ * Set or reset the simulated open drain mode of a GPIO (used only in sandbox
+ * test code)
+ *
+ * @param gp	GPIO number
+ * @param value	value to set (0 for enabled open drain mode, non-zero for
+ * 		disabled)
+ * @return -1 on error, 0 if ok
+ */
+int sandbox_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value);
+
+/**
+ * Return the state of the simulated open drain mode of a GPIO (used only in
+ * sandbox test code)
+ *
+ * @param gp	GPIO number
+ * @return -1 on error, 0 if GPIO is input, >0 if output
+ */
+int sandbox_gpio_get_open_drain(struct udevice *dev, unsigned offset);
+
+/**
  * Return the simulated direction of a GPIO (used only in sandbox test code)
  *
  * @param gp	GPIO number
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index a9b1efc..f6435a0 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -15,6 +15,7 @@ DECLARE_GLOBAL_DATA_PTR;
 /* Flags for each GPIO */
 #define GPIOF_OUTPUT	(1 << 0)	/* Currently set as an output */
 #define GPIOF_HIGH	(1 << 1)	/* Currently set high */
+#define GPIOF_ODR	(1 << 2)	/* Currently set to open drain mode */
 
 struct gpio_state {
 	const char *label;	/* label given by requester */
@@ -70,6 +71,16 @@ int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value)
 	return set_gpio_flag(dev, offset, GPIOF_HIGH, value);
 }
 
+int sandbox_gpio_get_open_drain(struct udevice *dev, unsigned offset)
+{
+	return get_gpio_flag(dev, offset, GPIOF_ODR);
+}
+
+int sandbox_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value)
+{
+	return set_gpio_flag(dev, offset, GPIOF_ODR, value);
+}
+
 int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset)
 {
 	return get_gpio_flag(dev, offset, GPIOF_OUTPUT);
@@ -124,6 +135,28 @@ static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
 	return sandbox_gpio_set_value(dev, offset, value);
 }
 
+/* read GPIO ODR value of port 'offset' */
+static int sb_gpio_get_open_drain(struct udevice *dev, unsigned offset)
+{
+	debug("%s: offset:%u\n", __func__, offset);
+
+	return sandbox_gpio_get_open_drain(dev, offset);
+}
+
+/* write GPIO ODR value to port 'offset' */
+static int sb_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value)
+{
+	debug("%s: offset:%u, value = %d\n", __func__, offset, value);
+
+	if (!sandbox_gpio_get_direction(dev, offset)) {
+		printf("sandbox_gpio: error: set_open_drain on input gpio %u\n",
+		       offset);
+		return -1;
+	}
+
+	return sandbox_gpio_set_open_drain(dev, offset, value);
+}
+
 static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
 {
 	if (get_gpio_flag(dev, offset, GPIOF_OUTPUT))
@@ -154,6 +187,8 @@ static const struct dm_gpio_ops gpio_sandbox_ops = {
 	.direction_output	= sb_gpio_direction_output,
 	.get_value		= sb_gpio_get_value,
 	.set_value		= sb_gpio_set_value,
+	.get_open_drain		= sb_gpio_get_open_drain,
+	.set_open_drain		= sb_gpio_set_open_drain,
 	.get_function		= sb_gpio_get_function,
 	.xlate			= sb_gpio_xlate,
 };
diff --git a/test/dm/gpio.c b/test/dm/gpio.c
index 727db18..b994523 100644
--- a/test/dm/gpio.c
+++ b/test/dm/gpio.c
@@ -75,6 +75,13 @@ static int dm_test_gpio(struct unit_test_state *uts)
 	ut_assertok(ops->set_value(dev, offset, 1));
 	ut_asserteq(1, ops->get_value(dev, offset));
 
+	/* Make it an open drain output, and reset it */
+	ut_asserteq(0, sandbox_gpio_get_open_drain(dev, offset));
+	ut_assertok(ops->set_open_drain(dev, offset, 1));
+	ut_asserteq(1, sandbox_gpio_get_open_drain(dev, offset));
+	ut_assertok(ops->set_open_drain(dev, offset, 0));
+	ut_asserteq(0, sandbox_gpio_get_open_drain(dev, offset));
+
 	/* Make it an input */
 	ut_assertok(ops->direction_input(dev, offset));
 	ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));

From 23d4e5ba49b878e01321be2af4e94f73389f4958 Mon Sep 17 00:00:00 2001
From: "Robert P. J. Day" <rpjday@crashcourse.ca>
Date: Wed, 13 Apr 2016 17:49:28 -0400
Subject: [PATCH 8/8] freescale: Tweak various Makefiles to remove redundancy,
 fix aesthetics

No intended functional change, just remove redundancies in some
Makefiles, and make whitespace aesthetics uniform.

Signed-off-by: Robert P. J. Day <rpjday@crashcourse.ca>
Reviewed-by: York Sun <york.sun@nxp.com>
---
 board/freescale/b4860qds/Makefile     |  6 +++---
 board/freescale/bsc9131rdb/Makefile   | 16 ++++++----------
 board/freescale/bsc9132qds/Makefile   |  9 +++------
 board/freescale/c29xpcie/Makefile     |  6 +++---
 board/freescale/p1010rdb/Makefile     | 12 ++++--------
 board/freescale/p1022ds/Makefile      | 12 +++++-------
 board/freescale/p1_p2_rdb_pc/Makefile | 17 +++++++----------
 board/freescale/p2041rdb/Makefile     |  2 +-
 board/freescale/t102xqds/Makefile     |  2 +-
 board/freescale/t102xrdb/Makefile     |  2 +-
 board/freescale/t208xqds/Makefile     |  6 ++----
 board/freescale/t208xrdb/Makefile     |  6 ++----
 board/freescale/t4qds/Makefile        |  6 +++---
 board/freescale/t4rdb/Makefile        |  9 +++++----
 14 files changed, 46 insertions(+), 65 deletions(-)

diff --git a/board/freescale/b4860qds/Makefile b/board/freescale/b4860qds/Makefile
index 0acd2a9..673d2ea 100644
--- a/board/freescale/b4860qds/Makefile
+++ b/board/freescale/b4860qds/Makefile
@@ -5,11 +5,11 @@
 #
 
 ifdef CONFIG_SPL_BUILD
-obj-y += spl.o
+obj-y	+= spl.o
 else
 obj-y	+= b4860qds.o
-obj-$(CONFIG_B4860QDS)+= eth_b4860qds.o
-obj-$(CONFIG_PCI)      += pci.o
+obj-$(CONFIG_B4860QDS)	+= eth_b4860qds.o
+obj-$(CONFIG_PCI)	+= pci.o
 endif
 
 obj-y	+= ddr.o
diff --git a/board/freescale/bsc9131rdb/Makefile b/board/freescale/bsc9131rdb/Makefile
index b26d3a1..8027750 100644
--- a/board/freescale/bsc9131rdb/Makefile
+++ b/board/freescale/bsc9131rdb/Makefile
@@ -13,15 +13,11 @@ endif
 endif
 
 ifdef MINIMAL
-
-obj-y	+= spl_minimal.o tlb.o law.o
-
+obj-y	+= spl_minimal.o
 else
-
-obj-y        += bsc9131rdb.o
-obj-y        += ddr.o
-obj-y        += law.o
-obj-y        += tlb.o
-#obj-y		+= bsc9131rdb_mux.o
-
+obj-y	+= bsc9131rdb.o
+obj-y	+= ddr.o
 endif
+
+obj-y	+= law.o
+obj-y	+= tlb.o
diff --git a/board/freescale/bsc9132qds/Makefile b/board/freescale/bsc9132qds/Makefile
index 2e4170f..5419335 100644
--- a/board/freescale/bsc9132qds/Makefile
+++ b/board/freescale/bsc9132qds/Makefile
@@ -13,14 +13,11 @@ endif
 endif
 
 ifdef MINIMAL
-
-obj-y	+= spl_minimal.o tlb.o law.o
-
+obj-y	+= spl_minimal.o
 else
-
 obj-y	+= bsc9132qds.o
 obj-y	+= ddr.o
+endif
+
 obj-y	+= law.o
 obj-y	+= tlb.o
-
-endif
diff --git a/board/freescale/c29xpcie/Makefile b/board/freescale/c29xpcie/Makefile
index 818484a..93b3cba 100644
--- a/board/freescale/c29xpcie/Makefile
+++ b/board/freescale/c29xpcie/Makefile
@@ -11,15 +11,15 @@ endif
 endif
 
 ifdef MINIMAL
-obj-y	+= spl_minimal.o tlb.o law.o
+obj-y	+= spl_minimal.o
 else
 ifdef CONFIG_SPL_BUILD
 obj-y	+= spl.o
 endif
-
 obj-y	+= c29xpcie.o
 obj-y	+= cpld.o
 obj-y	+= ddr.o
+endif
+
 obj-y	+= law.o
 obj-y	+= tlb.o
-endif
diff --git a/board/freescale/p1010rdb/Makefile b/board/freescale/p1010rdb/Makefile
index 660d1bb..86eb694 100644
--- a/board/freescale/p1010rdb/Makefile
+++ b/board/freescale/p1010rdb/Makefile
@@ -13,18 +13,14 @@ endif
 endif
 
 ifdef MINIMAL
-
-obj-y	+= spl_minimal.o tlb.o law.o
-
+obj-y	+= spl_minimal.o
 else
-
 ifdef CONFIG_SPL_BUILD
-obj-y += spl.o
+obj-y	+= spl.o
 endif
-
 obj-y	+= p1010rdb.o
 obj-y	+= ddr.o
+endif
+
 obj-y	+= law.o
 obj-y	+= tlb.o
-
-endif
diff --git a/board/freescale/p1022ds/Makefile b/board/freescale/p1022ds/Makefile
index a582127..9793853 100644
--- a/board/freescale/p1022ds/Makefile
+++ b/board/freescale/p1022ds/Makefile
@@ -13,17 +13,15 @@ endif
 endif
 
 ifdef MINIMAL
-
-obj-y        += spl_minimal.o tlb.o law.o
-
+obj-y	+= spl_minimal.o
 else
 ifdef CONFIG_SPL_BUILD
-obj-y += spl.o
+obj-y	+= spl.o
 endif
 obj-y	+= p1022ds.o
 obj-y	+= ddr.o
-obj-y	+= law.o
-obj-y	+= tlb.o
-
 obj-$(CONFIG_FSL_DIU_FB) += diu.o
 endif
+
+obj-y	+= law.o
+obj-y	+= tlb.o
diff --git a/board/freescale/p1_p2_rdb_pc/Makefile b/board/freescale/p1_p2_rdb_pc/Makefile
index a2a1f92..045d409 100644
--- a/board/freescale/p1_p2_rdb_pc/Makefile
+++ b/board/freescale/p1_p2_rdb_pc/Makefile
@@ -13,17 +13,14 @@ endif
 endif
 
 ifdef MINIMAL
-
-obj-y	+= spl_minimal.o tlb.o law.o
-
+obj-y	+= spl_minimal.o
 else
 ifdef CONFIG_SPL_BUILD
-obj-y += spl.o
+obj-y	+= spl.o
 endif
-
-obj-y        += p1_p2_rdb_pc.o
-obj-y        += ddr.o
-obj-y        += law.o
-obj-y        += tlb.o
-
+obj-y	+= p1_p2_rdb_pc.o
+obj-y	+= ddr.o
 endif
+
+obj-y	+= law.o
+obj-y	+= tlb.o
diff --git a/board/freescale/p2041rdb/Makefile b/board/freescale/p2041rdb/Makefile
index c74f4c6..a335ec6 100644
--- a/board/freescale/p2041rdb/Makefile
+++ b/board/freescale/p2041rdb/Makefile
@@ -7,6 +7,6 @@
 #
 
 obj-y	+= p2041rdb.o
-obj-y += cpld.o
+obj-y	+= cpld.o
 obj-y	+= ddr.o
 obj-y	+= eth.o
diff --git a/board/freescale/t102xqds/Makefile b/board/freescale/t102xqds/Makefile
index d94f230..afbc914 100644
--- a/board/freescale/t102xqds/Makefile
+++ b/board/freescale/t102xqds/Makefile
@@ -5,7 +5,7 @@
 #
 
 ifdef CONFIG_SPL_BUILD
-obj-y += spl.o
+obj-y	+= spl.o
 else
 obj-y	+= t102xqds.o
 obj-y	+= eth_t102xqds.o
diff --git a/board/freescale/t102xrdb/Makefile b/board/freescale/t102xrdb/Makefile
index 0520066..6452865 100644
--- a/board/freescale/t102xrdb/Makefile
+++ b/board/freescale/t102xrdb/Makefile
@@ -5,7 +5,7 @@
 #
 
 ifdef CONFIG_SPL_BUILD
-obj-y += spl.o
+obj-y	+= spl.o
 else
 obj-y   += t102xrdb.o
 obj-$(CONFIG_T1024RDB)   += cpld.o
diff --git a/board/freescale/t208xqds/Makefile b/board/freescale/t208xqds/Makefile
index 6cb72c9..ef04a26 100644
--- a/board/freescale/t208xqds/Makefile
+++ b/board/freescale/t208xqds/Makefile
@@ -7,10 +7,8 @@
 ifdef CONFIG_SPL_BUILD
 obj-y += spl.o
 else
-obj-$(CONFIG_T2080QDS) += t208xqds.o
-obj-$(CONFIG_T2080QDS) += eth_t208xqds.o
-obj-$(CONFIG_T2081QDS) += t208xqds.o
-obj-$(CONFIG_T2081QDS) += eth_t208xqds.o
+obj-$(CONFIG_T2080QDS) += t208xqds.o eth_t208xqds.o
+obj-$(CONFIG_T2081QDS) += t208xqds.o eth_t208xqds.o
 obj-$(CONFIG_PCI)      += pci.o
 endif
 
diff --git a/board/freescale/t208xrdb/Makefile b/board/freescale/t208xrdb/Makefile
index 9605f8b..cd8fe09 100644
--- a/board/freescale/t208xrdb/Makefile
+++ b/board/freescale/t208xrdb/Makefile
@@ -5,11 +5,9 @@
 #
 
 ifdef CONFIG_SPL_BUILD
-obj-y += spl.o
+obj-y	+= spl.o
 else
-obj-$(CONFIG_T2080RDB) += t208xrdb.o
-obj-$(CONFIG_T2080RDB) += eth_t208xrdb.o
-obj-$(CONFIG_T2080RDB) += cpld.o
+obj-$(CONFIG_T2080RDB) += t208xrdb.o eth_t208xrdb.o cpld.o
 obj-$(CONFIG_PCI)      += pci.o
 endif
 
diff --git a/board/freescale/t4qds/Makefile b/board/freescale/t4qds/Makefile
index bd2c1f1..731ccb0 100644
--- a/board/freescale/t4qds/Makefile
+++ b/board/freescale/t4qds/Makefile
@@ -5,12 +5,12 @@
 #
 
 ifdef CONFIG_SPL_BUILD
-obj-y += spl.o
+obj-y	+= spl.o
 else
-obj-$(CONFIG_T4240QDS) += t4240qds.o
-obj-$(CONFIG_T4240QDS)+= eth.o
+obj-$(CONFIG_T4240QDS)	+= t4240qds.o eth.o
 obj-$(CONFIG_PCI)	+= pci.o
 endif
+
 obj-y	+= ddr.o
 obj-y	+= law.o
 obj-y	+= tlb.o
diff --git a/board/freescale/t4rdb/Makefile b/board/freescale/t4rdb/Makefile
index 83b55ee..4f29eea 100644
--- a/board/freescale/t4rdb/Makefile
+++ b/board/freescale/t4rdb/Makefile
@@ -5,13 +5,14 @@
 #
 
 ifdef CONFIG_SPL_BUILD
-obj-y += spl.o
+obj-y	+= spl.o
 else
-obj-$(CONFIG_T4240RDB) += t4240rdb.o
-obj-y	+= cpld.o
-obj-y	+= eth.o
+obj-$(CONFIG_T4240RDB)	+= t4240rdb.o
+obj-y			+= cpld.o
+obj-y			+= eth.o
 obj-$(CONFIG_PCI)	+= pci.o
 endif
+
 obj-y	+= ddr.o
 obj-y	+= law.o
 obj-y	+= tlb.o