fsl: serdes: ensure accessing the initialized maps of serdes protocol

Up to now, the function is_serdes_configed() doesn't check if the map
of serdes protocol is initialized before accessing it. The function
is_serdes_configed() will get wrong result when it was called before
the serdes protocol maps initialized. As the first element of the map
isn't used for any device, so use it as the flag to indicate if the
map has been initialized.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: York Sun <york.sun@nxp.com>
diff --git a/arch/powerpc/cpu/mpc85xx/bsc9132_serdes.c b/arch/powerpc/cpu/mpc85xx/bsc9132_serdes.c
index 399b208..4b5cd99 100644
--- a/arch/powerpc/cpu/mpc85xx/bsc9132_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/bsc9132_serdes.c
@@ -68,6 +68,9 @@
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -79,6 +82,9 @@
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -90,4 +96,7 @@
 		enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/c29x_serdes.c b/arch/powerpc/cpu/mpc85xx/c29x_serdes.c
index 51972cb..74d27b9 100644
--- a/arch/powerpc/cpu/mpc85xx/c29x_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/c29x_serdes.c
@@ -32,6 +32,9 @@
 
 int is_serdes_configured(enum srds_prtcl device)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes1_prtcl_map;
 }
 
@@ -44,6 +47,9 @@
 	const struct serdes_config *ptr;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -59,4 +65,7 @@
 		enum srds_prtcl lane_prtcl = ptr->lanes[lane];
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c
index 9920839..ebc9b81 100644
--- a/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c
@@ -92,15 +92,27 @@
 	int ret = 0;
 
 #ifdef CONFIG_SYS_FSL_SRDS_1
+	if (!serdes1_prtcl_map[NONE])
+		fsl_serdes_init();
+
 	ret |= serdes1_prtcl_map[device];
 #endif
 #ifdef CONFIG_SYS_FSL_SRDS_2
+	if (!serdes2_prtcl_map[NONE])
+		fsl_serdes_init();
+
 	ret |= serdes2_prtcl_map[device];
 #endif
 #ifdef CONFIG_SYS_FSL_SRDS_3
+	if (!serdes3_prtcl_map[NONE])
+		fsl_serdes_init();
+
 	ret |= serdes3_prtcl_map[device];
 #endif
 #ifdef CONFIG_SYS_FSL_SRDS_4
+	if (!serdes4_prtcl_map[NONE])
+		fsl_serdes_init();
+
 	ret |= serdes4_prtcl_map[device];
 #endif
 
@@ -184,6 +196,9 @@
 	u32 cfg;
 	int lane;
 
+	if (serdes_prtcl_map[NONE])
+		return;
+
 	memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
 #ifdef CONFIG_SYS_FSL_ERRATUM_A007186
 	struct ccsr_sfp_regs  __iomem *sfp_regs =
@@ -325,6 +340,9 @@
 		else
 			serdes_prtcl_map[lane_prtcl] = 1;
 	}
+
+	/* Set the first element to indicate serdes has been initialized */
+	serdes_prtcl_map[NONE] = 1;
 }
 
 void fsl_serdes_init(void)
diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
index ba22f90..85739e9 100644
--- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
@@ -136,6 +136,9 @@
 	if (!(in_be32(&gur->rcwsr[5]) & FSL_CORENET_RCWSR5_SRDS_EN))
 		return 0;
 
+	if (!(serdes_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes_prtcl_map;
 }
 
@@ -514,6 +517,8 @@
 	if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0)
 		buf = buffer;
 #endif
+	if (serdes_prtcl_map & (1 << NONE))
+		return;
 
 	/* Is serdes enabled at all? */
 	if (!(in_be32(&gur->rcwsr[5]) & FSL_CORENET_RCWSR5_SRDS_EN))
@@ -857,6 +862,9 @@
 			     SRDS_RSTCTL_SDPD);
 	}
 #endif
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes_prtcl_map |= (1 << NONE);
 }
 
 const char *serdes_clock_to_string(u32 clock)
diff --git a/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c
index baf52d5..8c075f1 100644
--- a/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c
@@ -71,11 +71,19 @@
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 
 	if (ret)
 		return ret;
 
+	if (!(serdes2_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes2_prtcl_map;
 }
 
@@ -88,6 +96,10 @@
 	u32 tmp;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE) &&
+	    serdes2_prtcl_map & (1 << NONE))
+		return;
+
 	srds1_io_sel = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >>
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 
@@ -221,6 +233,9 @@
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	if (srds2_io_sel >= ARRAY_SIZE(serdes2_cfg_tbl)) {
 		printf("Invalid PORDEVSR[SRDS2_IO_SEL] = %d\n", srds2_io_sel);
 		return;
@@ -230,4 +245,7 @@
 		enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds2_io_sel][lane];
 		serdes2_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes2_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/mpc8544_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8544_serdes.c
index ed78a66..b27763e 100644
--- a/arch/powerpc/cpu/mpc85xx/mpc8544_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/mpc8544_serdes.c
@@ -34,11 +34,19 @@
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 
 	if (ret)
 		return ret;
 
+	if (!(serdes2_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes2_prtcl_map;
 }
 
@@ -50,6 +58,10 @@
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE) &&
+	    serdes2_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -61,6 +73,9 @@
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
 		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
 		return;
@@ -76,4 +91,7 @@
 
 	if (pordevsr & MPC85xx_PORDEVSR_SGMII3_DIS)
 		serdes2_prtcl_map &= ~(1 << SGMII_TSEC3);
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes2_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/mpc8548_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8548_serdes.c
index d146955..f1042d5 100644
--- a/arch/powerpc/cpu/mpc85xx/mpc8548_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/mpc8548_serdes.c
@@ -24,6 +24,9 @@
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -35,6 +38,9 @@
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL] = %x\n", srds1_cfg);
 
 	if (srds1_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -46,4 +52,7 @@
 		enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds1_cfg][lane];
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/mpc8568_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8568_serdes.c
index 9199f01..7c287a0 100644
--- a/arch/powerpc/cpu/mpc85xx/mpc8568_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/mpc8568_serdes.c
@@ -24,6 +24,9 @@
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -35,6 +38,9 @@
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -46,4 +52,7 @@
 		enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/mpc8569_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8569_serdes.c
index 6c80b5e..cc8ddb2 100644
--- a/arch/powerpc/cpu/mpc85xx/mpc8569_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/mpc8569_serdes.c
@@ -33,6 +33,9 @@
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -44,6 +47,9 @@
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -55,4 +61,7 @@
 		enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/mpc8572_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8572_serdes.c
index 3632eb5..1f0f474 100644
--- a/arch/powerpc/cpu/mpc85xx/mpc8572_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/mpc8572_serdes.c
@@ -28,6 +28,9 @@
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -39,6 +42,9 @@
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -62,4 +68,7 @@
 
 	if (!(pordevsr & MPC85xx_PORDEVSR_SGMII4_DIS))
 		serdes1_prtcl_map |= (1 << SGMII_TSEC4);
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/p1010_serdes.c b/arch/powerpc/cpu/mpc85xx/p1010_serdes.c
index 4b965f7..d8c0b62 100644
--- a/arch/powerpc/cpu/mpc85xx/p1010_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/p1010_serdes.c
@@ -33,11 +33,19 @@
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 
 	if (ret)
 		return ret;
 
+	if (!(serdes2_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes2_prtcl_map;
 }
 
@@ -49,6 +57,10 @@
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE) &&
+	    serdes2_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -60,6 +72,9 @@
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
 		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
 		return;
@@ -69,4 +84,7 @@
 		enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane];
 		serdes2_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes2_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/p1021_serdes.c b/arch/powerpc/cpu/mpc85xx/p1021_serdes.c
index 99a77bd..77b9439 100644
--- a/arch/powerpc/cpu/mpc85xx/p1021_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/p1021_serdes.c
@@ -41,6 +41,9 @@
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -55,6 +58,9 @@
 	int lane;
 	u32 mask, val;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -67,6 +73,9 @@
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	/* Init SERDES Receiver electrical idle detection control for PCIe */
 
 	/* Lane 0 is always PCIe 1 */
diff --git a/arch/powerpc/cpu/mpc85xx/p1022_serdes.c b/arch/powerpc/cpu/mpc85xx/p1022_serdes.c
index 14d17eb..88013d4 100644
--- a/arch/powerpc/cpu/mpc85xx/p1022_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/p1022_serdes.c
@@ -72,11 +72,19 @@
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 
 	if (ret)
 		return ret;
 
+	if (!(serdes2_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes2_prtcl_map;
 }
 
@@ -88,6 +96,10 @@
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE) &&
+	    serdes2_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -99,6 +111,9 @@
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
 		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
 		return;
@@ -108,4 +123,7 @@
 		enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane];
 		serdes2_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes2_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/p1023_serdes.c b/arch/powerpc/cpu/mpc85xx/p1023_serdes.c
index e83b0a3..b2b9f95 100644
--- a/arch/powerpc/cpu/mpc85xx/p1023_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/p1023_serdes.c
@@ -24,7 +24,12 @@
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 	return ret;
 }
 
@@ -36,6 +41,9 @@
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -47,4 +55,6 @@
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/p2020_serdes.c b/arch/powerpc/cpu/mpc85xx/p2020_serdes.c
index 59d402c..0890eaa 100644
--- a/arch/powerpc/cpu/mpc85xx/p2020_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/p2020_serdes.c
@@ -32,6 +32,9 @@
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -43,6 +46,9 @@
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -54,4 +60,7 @@
 		enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c b/arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c
index 2a7e3bf..ea4f4c8 100644
--- a/arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c
+++ b/arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c
@@ -29,11 +29,19 @@
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 
 	if (ret)
 		return ret;
 
+	if (!(serdes2_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes2_prtcl_map;
 }
 
@@ -46,6 +54,10 @@
 				MPC8610_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE) &&
+	    serdes2_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -57,6 +69,9 @@
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
 		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
 		return;
@@ -66,4 +81,7 @@
 		enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane];
 		serdes2_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes2_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c b/arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c
index cc0f8e9..5b12cbd 100644
--- a/arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c
+++ b/arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c
@@ -38,11 +38,19 @@
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 
 	if (ret)
 		return ret;
 
+	if (!(serdes2_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes2_prtcl_map;
 }
 
@@ -55,6 +63,10 @@
 				MPC8641_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE) &&
+	    serdes2_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -66,6 +78,9 @@
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
 		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
 		return;
@@ -75,4 +90,7 @@
 		enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane];
 		serdes2_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes2_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/include/asm/fsl_serdes.h b/arch/powerpc/include/asm/fsl_serdes.h
index 45e248e..cb259cc 100644
--- a/arch/powerpc/include/asm/fsl_serdes.h
+++ b/arch/powerpc/include/asm/fsl_serdes.h
@@ -10,6 +10,10 @@
 #include <config.h>
 
 enum srds_prtcl {
+	/*
+	 * Nobody will check whether the device 'NONE' has been configured,
+	 * So use it to indicate if the serdes_prtcl_map has been initialized.
+	 */
 	NONE = 0,
 	PCIE1,
 	PCIE2,