Merge remote-tracking branch 'fsl-linux-sdk/imx_3.14.y' into imx_3.14.y_android
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 06d8181..715db92 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -160,6 +160,7 @@
 	imx6dl-sabreauto-ecspi.dtb \
 	imx6dl-sabreauto-gpmi-weim.dtb \
 	imx6dl-sabresd.dtb \
+	imx6dl-sabresd-btwifi.dtb \
 	imx6dl-sabresd-enetirq.dtb \
 	imx6dl-sabresd-ldo.dtb \
 	imx6dl-sabresd-pf200.dtb \
@@ -177,19 +178,20 @@
 	imx6qp-sabreauto-flexcan1.dtb \
 	imx6qp-sabreauto-gpmi-weim.dtb \
 	imx6qp-sabresd.dtb \
+	imx6qp-sabresd-btwifi.dtb \
 	imx6qp-sabresd-ldo.dtb \
-	imx6qp-sabresd-uart.dtb \
+	imx6qp-sabresd-hdcp.dtb \
 	imx6q-sabrelite.dtb \
 	imx6q-sabresd.dtb \
-	imx6q-sabresd-ldo.dtb \
+	imx6q-sabresd-btwifi.dtb \
 	imx6q-sabresd-enetirq.dtb \
-	imx6q-sabresd-uart.dtb \
-	imx6q-sabresd-hdcp.dtb \
 	imx6q-sabresd-ldo.dtb \
+	imx6q-sabresd-hdcp.dtb \
 	imx6q-sbc6x.dtb \
 	imx6q-udoo.dtb \
 	imx6q-wandboard.dtb \
 	imx6sl-evk.dtb \
+	imx6sl-evk-btwifi.dtb \
 	imx6sl-evk-csi.dtb \
 	imx6sl-evk-ldo.dtb \
 	imx6sl-evk-pf200.dtb \
@@ -211,6 +213,7 @@
 	imx6sx-19x19-arm2-lcdif1.dtb \
 	imx6sx-19x19-arm2-gpmi-weim.dtb \
 	imx6sx-sdb.dtb \
+	imx6sx-sdb-btwifi.dtb \
 	imx6sx-sdb-ldo.dtb \
 	imx6sx-sdb-mqs.dtb \
 	imx6sx-sdb-reva.dtb \
@@ -230,6 +233,7 @@
 	imx6ul-14x14-ddr3-arm2-spdif.dtb \
 	imx6ul-14x14-ddr3-arm2-wm8958.dtb \
 	imx6ul-14x14-evk.dtb \
+	imx6ul-14x14-evk-btwifi.dtb \
 	imx6ul-14x14-evk-csi.dtb \
 	imx6ul-9x9-evk.dtb \
 	imx6ul-9x9-evk-ldo.dtb \
diff --git a/arch/arm/boot/dts/imx6dl-sabresd-btwifi.dts b/arch/arm/boot/dts/imx6dl-sabresd-btwifi.dts
new file mode 100644
index 0000000..814c935
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-sabresd-btwifi.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "imx6dl-sabresd.dts"
+#include "imx6qdl-sabresd-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6q-sabresd-btwifi.dts b/arch/arm/boot/dts/imx6q-sabresd-btwifi.dts
new file mode 100644
index 0000000..af65f3a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabresd-btwifi.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "imx6q-sabresd.dts"
+#include "imx6qdl-sabresd-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6q-sabresd-uart.dts b/arch/arm/boot/dts/imx6q-sabresd-uart.dts
deleted file mode 100644
index 6743731..0000000
--- a/arch/arm/boot/dts/imx6q-sabresd-uart.dts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "imx6q-sabresd.dts"
-
-/ {
-	leds {
-		compatible = "gpio-leds";
-		status = "disabled";
-	};
-};
-
-&uart5 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart5_1>;
-	fsl,uart-has-rtscts;
-	status = "okay";
-	/* for DTE mode, add below change */
-	/* fsl,dte-mode; */
-	/* pinctrl-0 = <&pinctrl_uart5dte_1>; */
-};
-
-&ecspi1 {
-	status = "disabled";
-};
diff --git a/arch/arm/boot/dts/imx6qdl-sabresd-btwifi.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd-btwifi.dtsi
new file mode 100644
index 0000000..d4c0569
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-sabresd-btwifi.dtsi
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * NOTE: This DTS file is written for plugging in Murata Wi-Fi/BT EVK into SD2
+ * slot using Murata i.MX InterConnect Ver 2.0 Adapter & connecting Bluetooth
+ * UART & control signals via ribbon cable.
+ * This configuration supports both WLAN and Bluetooth.
+ * WL_REG_ON/BT_REG_ON/WL_HOST_WAKE are connected via ribbon cable (J13 connector
+ * on board).
+ * ==> Hardware modification is required. Refer to schematic.
+ */
+
+/ {
+	leds {
+		compatible = "gpio-leds";
+		status = "disabled";
+	};
+
+	regulators {
+		wlreg_on: fixedregulator@100 {
+			compatible = "regulator-fixed";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			regulator-name = "wlreg_on";
+			gpio = <&gpio4 7 0>;
+			startup-delay-us = <100>;
+			enable-active-high;
+		};
+	};
+
+	bcmdhd_wlan_0: bcmdhd_wlan@0 {
+		compatible = "android,bcmdhd_wlan";
+		wlreg_on-supply = <&wlreg_on>;
+	};
+};
+
+&ecspi1 {
+	status = "disabled";
+};
+
+&iomuxc {
+	imx6qdl-sabresd-murata-v2 {
+		/* add MUXing entry for SD2 4-bit interface and configure control pins */
+		pinctrl_wifi: wifigrp {
+			fsl,pins = <
+				MX6QDL_PAD_SD2_CMD__SD2_CMD		0x17059
+				MX6QDL_PAD_SD2_CLK__SD2_CLK		0x10059
+				MX6QDL_PAD_SD2_DAT0__SD2_DATA0		0x17059
+				MX6QDL_PAD_SD2_DAT1__SD2_DATA1		0x17059
+				MX6QDL_PAD_SD2_DAT2__SD2_DATA2		0x17059
+				MX6QDL_PAD_SD2_DAT3__SD2_DATA3		0x17059
+				MX6QDL_PAD_KEY_ROW0__GPIO4_IO07		0x13069	/* WL_REG_ON */
+			>;
+		};
+	};
+};
+
+&uart5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart5_1>;
+	fsl,uart-has-rtscts;
+	status = "okay";
+	/* for DTE mode, add below change */
+	/* fsl,dte-mode; */
+	/* pinctrl-0 = <&pinctrl_uart5dte_1>; */
+};
+
+&usdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wifi>;
+	bus-width = <4>;
+	no-1-8-v;
+	wifi-host;
+};
diff --git a/arch/arm/boot/dts/imx6qp-sabresd-btwifi.dts b/arch/arm/boot/dts/imx6qp-sabresd-btwifi.dts
new file mode 100644
index 0000000..38d39ca
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qp-sabresd-btwifi.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "imx6qp-sabresd.dts"
+#include "imx6qdl-sabresd-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6qp-sabresd-hdcp.dts b/arch/arm/boot/dts/imx6qp-sabresd-hdcp.dts
new file mode 100644
index 0000000..8dce5ca
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qp-sabresd-hdcp.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "imx6qp-sabresd.dts"
+
+&hdmi_video {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hdmi_hdcp>;
+	fsl,hdcp;
+};
+
+&i2c2 {
+	status = "disable";
+};
diff --git a/arch/arm/boot/dts/imx6qp-sabresd-uart.dts b/arch/arm/boot/dts/imx6qp-sabresd-uart.dts
deleted file mode 100644
index d855aae..0000000
--- a/arch/arm/boot/dts/imx6qp-sabresd-uart.dts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2015 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "imx6qp-sabresd.dts"
-
-/ {
-	leds {
-		compatible = "gpio-leds";
-		status = "disabled";
-	};
-};
-
-&ecspi1 {
-	status = "disabled";
-};
-
-&uart5 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart5_1>;
-	fsl,uart-has-rtscts;
-	status = "okay";
-	/* for DTE mode, add below change */
-	/* fsl,dte-mode; */
-	/* pinctrl-0 = <&pinctrl_uart5dte_1>; */
-};
diff --git a/arch/arm/boot/dts/imx6qp-sabresd.dts b/arch/arm/boot/dts/imx6qp-sabresd.dts
index 0fb94e5..a4f066c 100644
--- a/arch/arm/boot/dts/imx6qp-sabresd.dts
+++ b/arch/arm/boot/dts/imx6qp-sabresd.dts
@@ -102,3 +102,7 @@
 	memory-region = <&memory>;
 	status = "okay";
 };
+
+&sata {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6sl-evk-btwifi.dts b/arch/arm/boot/dts/imx6sl-evk-btwifi.dts
new file mode 100644
index 0000000..86924c7
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sl-evk-btwifi.dts
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* NOTE: This DTS file is written for plugging in Murata Wi-Fi/BT EVK into SD1
+ * slot using Murata i.MX InterConnect Ver 1.0 Adapter AND wiring in control
+ * signals with SD Card Extender on SD3 slot.
+ * Bluetooth UART connect via SD1 EMMC/MMC Plus pinout.
+ * WL_REG_ON/BT_REG_ON/WL_HOST_WAKE are connected from SD Card Extender on SD3
+ * slot.
+ */
+#include "imx6sl-evk.dts"
+
+/ {
+	regulators {
+		wlreg_on: fixedregulator@100 {
+			compatible = "regulator-fixed";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			regulator-name = "wlreg_on";
+			gpio = <&gpio5 16 0>;
+			startup-delay-us = <100>;
+			enable-active-high;
+		};
+	};
+
+	bcmdhd_wlan_0: bcmdhd_wlan@0 {
+		compatible = "android,bcmdhd_wlan";
+		wlreg_on-supply = <&wlreg_on>;
+	};
+};
+
+&iomuxc {
+	imx6sl-evk-murata-v1_sdext {
+		/* Only MUX SD1_DAT0..3 lines so UART4 can be MUXed on higher data lines. */
+		pinctrl_wifi: wifigrp {
+			fsl,pins = <
+				MX6SL_PAD_SD1_CMD__SD1_CMD		0x17059
+				MX6SL_PAD_SD1_CLK__SD1_CLK		0x10059
+				MX6SL_PAD_SD1_DAT0__SD1_DATA0		0x17059
+				MX6SL_PAD_SD1_DAT1__SD1_DATA1		0x17059
+				MX6SL_PAD_SD1_DAT2__SD1_DATA2		0x17059
+				MX6SL_PAD_SD1_DAT3__SD1_DATA3		0x17059
+				MX6SL_PAD_SD3_DAT2__GPIO5_IO16		0x13069 /* WL_REG_ON */
+			>;
+		};
+
+		pinctrl_usdhc3_1: usdhc3grp-1 {
+			fsl,pins = <
+				MX6SL_PAD_SD3_CMD__SD3_CMD		0x17059
+				MX6SL_PAD_SD3_CLK__SD3_CLK		0x10059
+				MX6SL_PAD_SD3_DAT0__SD3_DATA0		0x17059
+			>;
+		};
+	};
+};
+
+&usdhc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wifi>;
+	bus-width = <4>;
+	no-1-8-v;
+	wifi-host;
+};
+
+&usdhc3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc3_1>;
+	bus-width = <1>;
+	no-1-8-v;
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-btwifi.dts b/arch/arm/boot/dts/imx6sx-sdb-btwifi.dts
new file mode 100644
index 0000000..575ed3c
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sdb-btwifi.dts
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * NOTE: This DTS file is written for plugging in Murata Wi-Fi/BT EVK into SD3
+ * slot using Murata i.MX InterConnect Ver 1.0 Adapter AND SD Card Extender on
+ * SD2 slot. Bluetooth UART connects via SD3 EMMC/MMC Plus pinout.
+ * WL_REG_ON/BT_REG_ON/WL_HOST_WAKE connect via SD Card Extender.
+ */
+
+#include "imx6sx-sdb.dts"
+
+/ {
+	regulators {
+		wlreg_on: fixedregulator@100 {
+			compatible = "regulator-fixed";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			regulator-name = "wlreg_on";
+			gpio = <&gpio6 10 0>;
+			startup-delay-us = <100>;
+			regulator-always-on;
+			enable-active-high;
+		};
+	};
+
+	bcmdhd_wlan_0: bcmdhd_wlan@0 {
+		compatible = "android,bcmdhd_wlan";
+		wlreg_on-supply = <&wlreg_on>;
+	};
+};
+
+&iomuxc {
+	imx6sx-sdb-murata-v1_sdext {
+		pinctrl_bt: btgrp {
+			fsl,pins = <
+				MX6SX_PAD_SD2_DATA3__GPIO6_IO_11	0x13069 /* BT_REG_ON */
+			>;
+		};
+
+		pinctrl_uart3: uart3grp {
+			fsl,pins = <
+				MX6SX_PAD_SD3_DATA4__UART3_RX		0x1b0b1
+				MX6SX_PAD_SD3_DATA5__UART3_TX		0x1b0b1
+				MX6SX_PAD_SD3_DATA7__UART3_CTS_B	0x1b0b1
+				MX6SX_PAD_SD3_DATA6__UART3_RTS_B	0x1b0b1
+			>;
+		};
+
+		/* change MUXing on SD2 slot for control signals. */
+		pinctrl_usdhc2_1: usdhc2grp-1 {
+			fsl,pins = <
+				MX6SX_PAD_SD2_CMD__USDHC2_CMD		0x17059
+				MX6SX_PAD_SD2_CLK__USDHC2_CLK		0x10059
+				MX6SX_PAD_SD2_DATA0__USDHC2_DATA0	0x17059
+			>;
+		};
+
+		/* Murata change SD3 to 4-bit SDIO only; use upper 4-bits for UART. */
+		pinctrl_wifi: wifigrp {
+			fsl,pins = <
+				MX6SX_PAD_SD3_CMD__USDHC3_CMD		0x17069
+				MX6SX_PAD_SD3_CLK__USDHC3_CLK		0x10071
+				MX6SX_PAD_SD3_DATA0__USDHC3_DATA0	0x17069
+				MX6SX_PAD_SD3_DATA1__USDHC3_DATA1	0x17069
+				MX6SX_PAD_SD3_DATA2__USDHC3_DATA2	0x17069
+				MX6SX_PAD_SD3_DATA3__USDHC3_DATA3	0x17069
+				MX6SX_PAD_KEY_COL0__GPIO2_IO_10		0x17059 /* CD */
+				MX6SX_PAD_KEY_ROW0__GPIO2_IO_15		0x17059 /* WP */
+				/* Murata Module control signals */
+				MX6SX_PAD_SD2_DATA2__GPIO6_IO_10	0x13069 /* WL_REG_ON */
+			>;
+		};
+	};
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart3
+		     &pinctrl_bt>;
+	fsl,uart-has-rtscts;
+	status = "okay";
+};
+
+&usdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2_1>;
+	bus-width = <1>;
+};
+
+&usdhc3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wifi>;
+	bus-width = <4>;
+	no-1-8-v;	/* force 3.3V VIO */
+	wifi-host;	/* pull in card detect mechanism for BCMDHD driver */
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk-btwifi.dts b/arch/arm/boot/dts/imx6ul-14x14-evk-btwifi.dts
new file mode 100644
index 0000000..97a21dc
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk-btwifi.dts
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * NOTE: This DTS file is written for plugging in Murata Wi-Fi/BT EVK into Slot
+ * SD1 and using Murata i.MX InterConnect Ver 2.0 Adapter. Bluetooth UART &
+ * control signals are connected via ribbon cable (J1701 connector).
+ */
+
+#include "imx6ul-14x14-evk.dts"
+
+/ {
+	regulators {
+		wlreg_on: fixedregulator@100 {
+			compatible = "regulator-fixed";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			regulator-name = "wlreg_on";
+			gpio = <&gpio5 1 0>;
+			startup-delay-us = <100>;
+			enable-active-high;
+		};
+	};
+
+	bcmdhd_wlan_0: bcmdhd_wlan@0 {
+		compatible = "android,bcmdhd_wlan";
+		wlreg_on-supply = <&wlreg_on>;
+	};
+};
+
+&iomuxc {
+	imx6ul-evk-murata-v2 {
+		pinctrl_wifi: wifigrp {
+			fsl,pins = <
+				MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x03029
+			>;
+		};
+	};
+};
+
+&usdhc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_wifi>;
+	no-1-8-v;
+	wifi-host; /* add hook for SD card detect mechanism for BCMDHD driver */
+};
diff --git a/arch/arm/configs/imx_v7_mfg_defconfig b/arch/arm/configs/imx_v7_mfg_defconfig
index 3093eec..2a88710 100644
--- a/arch/arm/configs/imx_v7_mfg_defconfig
+++ b/arch/arm/configs/imx_v7_mfg_defconfig
@@ -302,6 +302,7 @@
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_UTF8=y
+CONFIG_DEBUG_FS=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_SCHED_DEBUG is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c
index 9770a5f..a5e0412 100644
--- a/arch/arm/mach-imx/anatop.c
+++ b/arch/arm/mach-imx/anatop.c
@@ -45,6 +45,8 @@
 #define BM_ANADIG_REG_CORE_REG2			(0x1f << 18)
 #define BP_ANADIG_REG_CORE_REG2			(18)
 #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG	0x1000
+#define BM_ANADIG_ANA_MISC0_V2_STOP_MODE_CONFIG	0x800
+#define BM_ANADIG_ANA_MISC0_V3_STOP_MODE_CONFIG	0xc00
 #define BM_ANADIG_ANA_MISC2_REG1_STEP_TIME	(0x3 << 26)
 #define BP_ANADIG_ANA_MISC2_REG1_STEP_TIME	(26)
 /* Below MISC0_DISCON_HIGH_SNVS is only for i.MX6SL */
@@ -61,14 +63,20 @@
 
 static void imx_anatop_enable_weak2p5(bool enable)
 {
-	u32 reg, val;
+	u32 reg, val, mask;
 
 	regmap_read(anatop, ANADIG_ANA_MISC0, &val);
 
+	if (cpu_is_imx6sx() || cpu_is_imx6ul())
+		mask = BM_ANADIG_ANA_MISC0_V3_STOP_MODE_CONFIG;
+	else if (cpu_is_imx6sl())
+		mask = BM_ANADIG_ANA_MISC0_V2_STOP_MODE_CONFIG;
+	else
+		mask = BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG;
+
 	/* can only be enabled when stop_mode_config is clear. */
 	reg = ANADIG_REG_2P5;
-	reg += (enable && (val & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) ?
-		REG_SET : REG_CLR;
+	reg += (enable && (val & mask) == 0) ? REG_SET : REG_CLR;
 	regmap_write(anatop, reg, BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG);
 }
 
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index ada6f20..e64384e 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -812,6 +812,9 @@
 		imx_clk_set_parent(clk[IMX6QDL_CLK_IPU2_SEL], clk[IMX6QDL_CLK_MMDC_CH0_AXI]);
 	}
 
+	imx_clk_set_parent(clk[IMX6QDL_CLK_AXI_ALT_SEL], clk[IMX6QDL_CLK_PLL3_PFD1_540M]);
+	imx_clk_set_parent(clk[IMX6QDL_CLK_AXI_SEL], clk[IMX6QDL_CLK_AXI_ALT_SEL]);
+
 	/*
 	 * The gpmi needs 100MHz frequency in the EDO/Sync mode,
 	 * We can not get the 100MHz from the pll2_pfd0_352m.
@@ -868,8 +871,8 @@
 	if (IS_ENABLED(CONFIG_PCI_IMX6))
 		imx_clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF]);
 
-	/* set eim_slow to 132Mhz */
-	imx_clk_set_rate(clk[IMX6QDL_CLK_EIM_SLOW], 132000000);
+	/* set eim_slow to 135Mhz */
+	imx_clk_set_rate(clk[IMX6QDL_CLK_EIM_SLOW], 135000000);
 
 	/*
 	 * Enable clocks only after both parent and rate are all initialized
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 8a2cd5c..69422dc 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -648,7 +648,7 @@
 	* which is present on mx6q, and not on mx53,
 	* we should use sg_tablesize = 1 for reliable operation
 	*/
-	if (imxpriv->type == AHCI_IMX6Q) {
+	if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
 		dma_addr_t dma;
 
 		ahci_platform_sht.sg_tablesize = 1;
diff --git a/drivers/cpufreq/imx7-cpufreq.c b/drivers/cpufreq/imx7-cpufreq.c
index 28d4cdd..a620cf0 100644
--- a/drivers/cpufreq/imx7-cpufreq.c
+++ b/drivers/cpufreq/imx7-cpufreq.c
@@ -181,7 +181,7 @@
 	pll_arm = devm_clk_get(cpu_dev, "pll_arm");
 	pll_sys_main = devm_clk_get(cpu_dev, "pll_sys_main");
 
-	if (IS_ERR(arm_clk) | IS_ERR(arm_src) | IS_ERR(pll_arm) |
+	if (IS_ERR(arm_clk) || IS_ERR(arm_src) || IS_ERR(pll_arm) ||
 	    IS_ERR(pll_sys_main)) {
 		dev_err(cpu_dev, "failed to get clocks\n");
 		ret = -ENOENT;
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index be1c36e..d89381c 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -353,6 +353,7 @@
 	struct gen_pool 		*iram_pool;
 	u32                             spba_start_addr;
 	u32                             spba_end_addr;
+	bool				suspend_off;
 };
 
 static struct sdma_driver_data sdma_imx31 = {
@@ -984,7 +985,7 @@
 	/*
 	 * restore back context since context may loss if mega/fast OFF
 	 */
-	if (!readl_relaxed(sdma->regs + SDMA_H_C0PTR)) {
+	if (sdma->suspend_off) {
 		if (sdma_load_context(sdmac)) {
 			dev_err(sdmac->sdma->dev, "context load failed.\n");
 			return -EINVAL;
@@ -2175,6 +2176,8 @@
 	struct sdma_engine *sdma = platform_get_drvdata(pdev);
 	int i;
 
+	sdma->suspend_off = false;
+
 	/* Do nothing if not i.MX6SX or i.MX7D*/
 	if (sdma->drvdata != &sdma_imx6sx && sdma->drvdata != &sdma_imx7d)
 		return 0;
@@ -2219,6 +2222,9 @@
 		clk_disable(sdma->clk_ahb);
 		return 0;
 	}
+
+	sdma->suspend_off = true;
+
 	/* restore regs and load firmware */
 	for (i = 0; i < MXC_SDMA_SAVED_REG_NUM; i++) {
 		/*
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index a33eb04..e6fab94 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -672,7 +672,6 @@
 
 static const struct dev_pm_ops wm8994_pm_ops = {
 	SET_RUNTIME_PM_OPS(wm8994_suspend, wm8994_resume, NULL)
-	SET_SYSTEM_SLEEP_PM_OPS(wm8994_suspend, wm8994_resume)
 };
 
 static struct i2c_driver wm8994_i2c_driver = {
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index 9fa6ec4..5e8d55f 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -22,12 +22,16 @@
 #include <linux/clk.h>
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
+#include <linux/debugfs.h>
 
 
 #include "gpmi-nand.h"
 #include "gpmi-regs.h"
 #include "bch-regs.h"
 
+/* export the bch geometry to dbgfs */
+static struct debugfs_blob_wrapper dbg_bch_geo;
+
 static struct timing_threshod timing_default_threshold = {
 	.max_data_setup_cycles       = (BM_GPMI_TIMING0_DATA_SETUP >>
 						BP_GPMI_TIMING0_DATA_SETUP),
@@ -229,7 +233,8 @@
 		"ECC Strength           : %u\n"
 		"Page Size in Bytes     : %u\n"
 		"Metadata Size in Bytes : %u\n"
-		"ECC Chunk Size in Bytes: %u\n"
+		"ECC Chunk0 Size in Bytes: %u\n"
+		"ECC Chunkn Size in Bytes: %u\n"
 		"ECC Chunk Count        : %u\n"
 		"Payload Size in Bytes  : %u\n"
 		"Auxiliary Size in Bytes: %u\n"
@@ -240,7 +245,8 @@
 		geo->ecc_strength,
 		geo->page_size,
 		geo->metadata_size,
-		geo->ecc_chunk_size,
+		geo->ecc_chunk0_size,
+		geo->ecc_chunkn_size,
 		geo->ecc_chunk_count,
 		geo->payload_size,
 		geo->auxiliary_size,
@@ -255,23 +261,40 @@
 	struct resources *r = &this->resources;
 	struct bch_geometry *bch_geo = &this->bch_geometry;
 	unsigned int block_count;
-	unsigned int block_size;
+	unsigned int block0_size;
+	unsigned int blockn_size;
 	unsigned int metadata_size;
 	unsigned int ecc_strength;
 	unsigned int page_size;
 	unsigned int gf_len;
 	int ret;
+	struct dentry *dbg_root;
 
 	if (common_nfc_set_geometry(this))
 		return !0;
 
 	block_count   = bch_geo->ecc_chunk_count - 1;
-	block_size    = bch_geo->ecc_chunk_size;
+	block0_size    = bch_geo->ecc_chunk0_size;
+	blockn_size    = bch_geo->ecc_chunkn_size;
 	metadata_size = bch_geo->metadata_size;
 	ecc_strength  = bch_geo->ecc_strength >> 1;
 	page_size     = bch_geo->page_size;
 	gf_len        = bch_geo->gf_len;
 
+	dbg_root = debugfs_create_dir("gpmi-nand", NULL);
+	if (!dbg_root) {
+		dev_err(this->dev, "failed to create debug directory\n");
+		return -EINVAL;
+	}
+
+	dbg_bch_geo.data = (void *)bch_geo;
+	dbg_bch_geo.size = sizeof(struct bch_geometry);
+	if (!debugfs_create_blob("bch_geometry", S_IRUGO,
+				dbg_root, &dbg_bch_geo)) {
+		dev_err(this->dev, "failed to create debug bch geometry\n");
+		return -EINVAL;
+	}
+
 	ret = pm_runtime_get_sync(this->dev);
 	if (ret < 0) {
 		dev_err(this->dev, "Failed to enable clock\n");
@@ -295,18 +318,18 @@
 			| BF_BCH_FLASH0LAYOUT0_META_SIZE(metadata_size)
 			| BF_BCH_FLASH0LAYOUT0_ECC0(ecc_strength, this)
 			| BF_BCH_FLASH0LAYOUT0_GF(gf_len, this)
-			| BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(block_size, this),
+			| BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(block0_size, this),
 			r->bch_regs + HW_BCH_FLASH0LAYOUT0);
 
 	writel(BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size)
 			| BF_BCH_FLASH0LAYOUT1_ECCN(ecc_strength, this)
 			| BF_BCH_FLASH0LAYOUT1_GF(gf_len, this)
-			| BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(block_size, this),
+			| BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(blockn_size, this),
 			r->bch_regs + HW_BCH_FLASH0LAYOUT1);
 
-	/* Set erase threshold to gf/2 for mx6ul, mx6qp and mx7 */
+	/* Set erase threshold to ecc strength for mx6ul, mx6qp and mx7 */
 	if (GPMI_IS_MX6QP(this) || GPMI_IS_MX7(this) || GPMI_IS_MX6UL(this))
-		writel(BF_BCH_MODE_ERASE_THRESHOLD(gf_len/2),
+		writel(BF_BCH_MODE_ERASE_THRESHOLD(ecc_strength),
 			r->bch_regs + HW_BCH_MODE);
 
 	/* Set *all* chip selects to use layout 0. */
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 21f3c55..7a0ac23 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -152,6 +152,36 @@
 	return geo->ecc_strength <= this->devdata->bch_max_ecc_strength;
 }
 
+static inline bool bbm_in_data_chunk(struct gpmi_nand_data *this,
+		unsigned int *chunk_num)
+{
+	struct bch_geometry *geo = &this->bch_geometry;
+	struct mtd_info *mtd = &this->mtd;
+	unsigned int i, j;
+
+	if (geo->ecc_chunk0_size != geo->ecc_chunk0_size) {
+		dev_err(this->dev, "The size of chunk0 must equal to chunkn\n");
+		return false;
+	}
+
+	i = (mtd->writesize * 8 - geo->metadata_size * 8) /
+		(geo->gf_len * geo->ecc_strength +
+				geo->ecc_chunkn_size * 8);
+
+	j = (mtd->writesize * 8 - geo->metadata_size * 8) -
+		(geo->gf_len * geo->ecc_strength +
+				geo->ecc_chunkn_size * 8) * i;
+
+	if (j < geo->ecc_chunkn_size * 8) {
+		*chunk_num = i+1;
+		dev_dbg(this->dev, "Set ecc to %d and bbm in chunk %d\n",
+				geo->ecc_strength, *chunk_num);
+		return true;
+	}
+
+	return false;
+}
+
 /*
  * If we can get the ECC information from the nand chip, we do not
  * need to calculate them ourselves.
@@ -182,15 +212,14 @@
 			chip->ecc_strength_ds, chip->ecc_step_ds);
 		return -EINVAL;
 	}
-	geo->ecc_chunk_size = chip->ecc_step_ds;
+	geo->ecc_chunk0_size = chip->ecc_step_ds;
+	geo->ecc_chunkn_size = chip->ecc_step_ds;
 	geo->ecc_strength = round_up(chip->ecc_strength_ds, 2);
 	if (!gpmi_check_ecc(this))
 		return -EINVAL;
-	/* set the ecc strength to the maximum ecc controller can support */
-	geo->ecc_strength = this->devdata->bch_max_ecc_strength;
 
 	/* Keep the C >= O */
-	if (geo->ecc_chunk_size < mtd->oobsize) {
+	if (geo->ecc_chunkn_size < mtd->oobsize) {
 		dev_err(this->dev,
 			"unsupported nand chip. ecc size: %d, oob size : %d\n",
 			chip->ecc_step_ds, mtd->oobsize);
@@ -200,7 +229,7 @@
 	/* The default value, see comment in the legacy_set_geometry(). */
 	geo->metadata_size = 10;
 
-	geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size;
+	geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size;
 
 	/*
 	 * Now, the NAND chip with 2K page(data chunk is 512byte) shows below:
@@ -278,6 +307,131 @@
 	return 0;
 }
 
+static int set_geometry_for_large_oob(struct gpmi_nand_data *this)
+{
+	struct bch_geometry *geo = &this->bch_geometry;
+	struct mtd_info *mtd = &this->mtd;
+	struct nand_chip *chip = mtd->priv;
+	unsigned int block_mark_bit_offset;
+	unsigned int max_ecc;
+	unsigned int bbm_chunk;
+	unsigned int i;
+
+
+	/* sanity check for the minimum ecc nand required */
+	if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
+		return -EINVAL;
+	geo->ecc_strength = chip->ecc_strength_ds;
+
+	/* check if platform can support this nand */
+	if (!gpmi_check_ecc(this)) {
+		dev_err(this->dev,
+				"unsupported NAND chip,\
+				minimum ecc required %d\n"
+				, geo->ecc_strength);
+		return -EINVAL;
+	}
+
+	/* calculate the maximum ecc platform can support*/
+	geo->metadata_size = 10;
+	geo->gf_len = 14;
+	geo->ecc_chunk0_size = 1024;
+	geo->ecc_chunkn_size = 1024;
+	geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size;
+	max_ecc = min(get_ecc_strength(this),
+			this->devdata->bch_max_ecc_strength);
+
+	/* search a supported ecc strength that makes bbm */
+	/* located in data chunk  */
+	geo->ecc_strength = chip->ecc_strength_ds;
+	while (!(geo->ecc_strength > max_ecc)) {
+		if (bbm_in_data_chunk(this, &bbm_chunk))
+			goto geo_setting;
+		geo->ecc_strength += 2;
+	}
+
+	/* if none of them works, keep using the minimum ecc */
+	/* nand required but changing ecc page layout  */
+	geo->ecc_strength = chip->ecc_strength_ds;
+	/* add extra ecc for meta data */
+	geo->ecc_chunk0_size = 0;
+	geo->ecc_chunk_count = (mtd->writesize / geo->ecc_chunkn_size) + 1;
+	geo->ecc_for_meta = 1;
+	/* check if oob can afford this extra ecc chunk */
+	if (mtd->oobsize * 8 < geo->metadata_size * 8 +
+			geo->gf_len * geo->ecc_strength
+			* geo->ecc_chunk_count) {
+		dev_err(this->dev, "unsupported NAND chip with new layout\n");
+		return -EINVAL;
+	}
+
+	/* calculate in which chunk bbm located */
+	bbm_chunk = (mtd->writesize * 8 - geo->metadata_size * 8 -
+		geo->gf_len * geo->ecc_strength) /
+		(geo->gf_len * geo->ecc_strength +
+				geo->ecc_chunkn_size * 8) + 1;
+
+geo_setting:
+
+	geo->page_size = mtd->writesize + mtd->oobsize;
+	geo->payload_size = mtd->writesize;
+
+	/*
+	 * The auxiliary buffer contains the metadata and the ECC status. The
+	 * metadata is padded to the nearest 32-bit boundary. The ECC status
+	 * contains one byte for every ECC chunk, and is also padded to the
+	 * nearest 32-bit boundary.
+	 */
+	geo->auxiliary_status_offset = ALIGN(geo->metadata_size, 4);
+	geo->auxiliary_size = ALIGN(geo->metadata_size, 4)
+				+ ALIGN(geo->ecc_chunk_count, 4);
+
+	if (!this->swap_block_mark)
+		return 0;
+
+	/* calculate the number of ecc chunk behind the bbm */
+	i = (mtd->writesize / geo->ecc_chunkn_size) - bbm_chunk + 1;
+
+	block_mark_bit_offset = mtd->writesize * 8 -
+		(geo->ecc_strength * geo->gf_len * (geo->ecc_chunk_count - i)
+				+ geo->metadata_size * 8);
+
+	geo->block_mark_byte_offset = block_mark_bit_offset / 8;
+	geo->block_mark_bit_offset  = block_mark_bit_offset % 8;
+
+	dev_dbg(this->dev, "BCH Geometry :\n"
+		"GF length              : %u\n"
+		"ECC Strength           : %u\n"
+		"Page Size in Bytes     : %u\n"
+		"Metadata Size in Bytes : %u\n"
+		"ECC Chunk0 Size in Bytes: %u\n"
+		"ECC Chunkn Size in Bytes: %u\n"
+		"ECC Chunk Count        : %u\n"
+		"Payload Size in Bytes  : %u\n"
+		"Auxiliary Size in Bytes: %u\n"
+		"Auxiliary Status Offset: %u\n"
+		"Block Mark Byte Offset : %u\n"
+		"Block Mark Bit Offset  : %u\n"
+		"Block Mark in chunk	: %u\n"
+		"Ecc for Meta data	: %u\n",
+		geo->gf_len,
+		geo->ecc_strength,
+		geo->page_size,
+		geo->metadata_size,
+		geo->ecc_chunk0_size,
+		geo->ecc_chunkn_size,
+		geo->ecc_chunk_count,
+		geo->payload_size,
+		geo->auxiliary_size,
+		geo->auxiliary_status_offset,
+		geo->block_mark_byte_offset,
+		geo->block_mark_bit_offset,
+		bbm_chunk,
+		geo->ecc_for_meta);
+
+	return 0;
+}
+
 static int legacy_set_geometry(struct gpmi_nand_data *this)
 {
 	struct bch_geometry *geo = &this->bch_geometry;
@@ -297,13 +451,15 @@
 	geo->gf_len = 13;
 
 	/* The default for chunk size. */
-	geo->ecc_chunk_size = 512;
-	while (geo->ecc_chunk_size < mtd->oobsize) {
-		geo->ecc_chunk_size *= 2; /* keep C >= O */
+	geo->ecc_chunk0_size = 512;
+	geo->ecc_chunkn_size = 512;
+	while (geo->ecc_chunkn_size < mtd->oobsize) {
+		geo->ecc_chunk0_size *= 2; /* keep C >= O */
+		geo->ecc_chunkn_size *= 2; /* keep C >= O */
 		geo->gf_len = 14;
 	}
 
-	geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size;
+	geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size;
 
 	/* We use the same ECC strength for all chunks. */
 	geo->ecc_strength = get_ecc_strength(this);
@@ -393,15 +549,24 @@
 
 int common_nfc_set_geometry(struct gpmi_nand_data *this)
 {
+	struct mtd_info *mtd = &this->mtd;
+	struct nand_chip *chip = mtd->priv;
 
-	if ((of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc"))
-				|| legacy_set_geometry(this))
-		/* To align with the kobs-ng, use the maximum ecc strength */
-		/* controller can support, rather than the minimum ecc nand */
-		/* spec required. */
-		return set_geometry_by_ecc_info(this);
+	if (chip->ecc_strength_ds > this->devdata->bch_max_ecc_strength) {
+		dev_err(this->dev,
+			"unsupported NAND chip, minimum ecc required %d\n"
+			, chip->ecc_strength_ds);
+		return -EINVAL;
+	}
 
-	return 0;
+	if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0) &&
+			!(mtd->oobsize > 1024))
+		return legacy_set_geometry(this);
+
+	if (mtd->oobsize > 1024 || chip->ecc_step_ds < mtd->oobsize)
+		return set_geometry_for_large_oob(this);
+
+	return set_geometry_by_ecc_info(this);
 }
 
 struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)
@@ -1035,6 +1200,61 @@
 	p[1] = (p[1] & mask) | (from_oob >> (8 - bit));
 }
 
+static bool gpmi_erased_check(struct gpmi_nand_data *this,
+			unsigned char *data, unsigned int chunk, int page,
+			unsigned int *max_bitflips)
+{
+	struct nand_chip *chip = &this->nand;
+	struct mtd_info	*mtd = &this->mtd;
+	struct bch_geometry *geo = &this->bch_geometry;
+	int base = geo->ecc_chunkn_size * chunk;
+	unsigned int flip_bits = 0, flip_bits_noecc = 0;
+	uint64_t *buf = (uint64_t *)this->data_buffer_dma;
+	unsigned int threshold;
+	int i;
+
+	threshold = geo->gf_len / 2;
+	if (threshold > geo->ecc_strength)
+		threshold = geo->ecc_strength;
+
+	/* Count bitflips */
+	for (i = 0; i < geo->ecc_chunkn_size; i++) {
+		flip_bits += hweight8(~data[base + i]);
+		if (flip_bits > threshold)
+			return false;
+	}
+
+	/*
+	 * Read out the whole page with ECC disabled, and check it again,
+	 * This is more strict then just read out a chunk, and it makes
+	 * the code more simple.
+	 */
+	chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+	chip->read_buf(mtd, (uint8_t *)buf, mtd->writesize);
+
+	/* Count the bitflips for the no ECC buffer */
+	for (i = 0; i < mtd->writesize / 8; i++) {
+		flip_bits_noecc += hweight64(~buf[i]);
+		if (flip_bits_noecc > threshold)
+			return false;
+	}
+
+	/* Tell the upper layer the bitflips we corrected. */
+	mtd->ecc_stats.corrected += flip_bits;
+	*max_bitflips = max_t(unsigned int, *max_bitflips, flip_bits);
+
+	/*
+	 * The geo->payload_size maybe not equal to the page size
+	 * when the Subpage-Read is enabled.
+	 */
+	memset(data, 0xff, geo->payload_size);
+
+	dev_dbg(this->dev, "The page(%d) is an erased page(%d,%d,%d,%d).\n",
+		page, chunk, threshold, flip_bits, flip_bits_noecc);
+
+	return true;
+}
+
 static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 				uint8_t *buf, int oob_required, int page)
 {
@@ -1094,6 +1314,9 @@
 		}
 
 		if (*status == STATUS_UNCORRECTABLE) {
+			if (gpmi_erased_check(this, payload_virt, i,
+						page, &max_bitflips))
+				break;
 			mtd->ecc_stats.failed++;
 			continue;
 		}
@@ -1164,9 +1387,23 @@
 		return gpmi_ecc_read_page(mtd, chip, buf, 0, page);
 	}
 
+	/*
+	 * if there is an ECC dedicate for meta:
+	 * - need to add an extra ECC size when calculating col and page_size,
+	 *   if the meta size is NOT zero.
+	 *
+	 * - chunk0 size need to set to the same size as other chunks,
+	 *   if the meta size is zero.
+	 */
+
 	meta = geo->metadata_size;
 	if (first) {
-		col = meta + (size + ecc_parity_size) * first;
+		if (geo->ecc_for_meta)
+			col = meta + ecc_parity_size
+				+ (size + ecc_parity_size) * first;
+		else
+			col = meta + (size + ecc_parity_size) * first;
+
 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, col, -1);
 
 		meta = 0;
@@ -1179,21 +1416,37 @@
 
 	/* change the BCH registers and bch_geometry{} */
 	n = last - first + 1;
-	page_size = meta + (size + ecc_parity_size) * n;
+
+	if (geo->ecc_for_meta && meta)
+		page_size = meta + ecc_parity_size
+			+ (size + ecc_parity_size) * n;
+	else
+		page_size = meta + (size + ecc_parity_size) * n;
 
 	r1_new &= ~(BM_BCH_FLASH0LAYOUT0_NBLOCKS |
 			BM_BCH_FLASH0LAYOUT0_META_SIZE);
-	r1_new |= BF_BCH_FLASH0LAYOUT0_NBLOCKS(n - 1)
+	r1_new |= BF_BCH_FLASH0LAYOUT0_NBLOCKS(
+			(geo->ecc_for_meta && meta) ? n : n - 1)
 			| BF_BCH_FLASH0LAYOUT0_META_SIZE(meta);
+
+	/* set chunk0 size if meta size is 0 */
+	if (!meta) {
+		if (GPMI_IS_MX6(this) || GPMI_IS_MX7(this))
+			r1_new &= ~MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE;
+		else
+			r1_new &= ~BM_BCH_FLASH0LAYOUT0_DATA0_SIZE;
+		r1_new |= BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(size, this);
+	}
 	writel(r1_new, bch_regs + HW_BCH_FLASH0LAYOUT0);
 
 	r2_new &= ~BM_BCH_FLASH0LAYOUT1_PAGE_SIZE;
 	r2_new |= BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size);
 	writel(r2_new, bch_regs + HW_BCH_FLASH0LAYOUT1);
 
-	geo->ecc_chunk_count = n;
+	geo->ecc_chunk_count = (geo->ecc_for_meta && meta) ? n + 1 : n;
 	geo->payload_size = n * size;
 	geo->page_size = page_size;
+	geo->metadata_size = meta;
 	geo->auxiliary_status_offset = ALIGN(meta, 4);
 
 	dev_dbg(this->dev, "page:%d(%d:%d)%d, chunk:(%d:%d), BCH PG size:%d\n",
@@ -1724,7 +1977,7 @@
 	ecc->read_oob	= gpmi_ecc_read_oob;
 	ecc->write_oob	= gpmi_ecc_write_oob;
 	ecc->mode	= NAND_ECC_HW;
-	ecc->size	= bch_geo->ecc_chunk_size;
+	ecc->size	= bch_geo->ecc_chunkn_size;
 	ecc->strength	= bch_geo->ecc_strength;
 	ecc->layout	= &gpmi_hw_ecclayout;
 
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index 5b0e141..7ee51fd 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -39,9 +39,9 @@
  * @page_size:                The size, in bytes, of a physical page, including
  *                            both data and OOB.
  * @metadata_size:            The size, in bytes, of the metadata.
- * @ecc_chunk_size:           The size, in bytes, of a single ECC chunk. Note
- *                            the first chunk in the page includes both data and
- *                            metadata, so it's a bit larger than this value.
+ * @ecc_chunk0_size:          The size, in bytes, of a first ECC chunk.
+ * @ecc_chunkn_size:          The size, in bytes, of a single ECC chunk after
+ *                            the first chunk in the page.
  * @ecc_chunk_count:          The number of ECC chunks in the page,
  * @payload_size:             The size, in bytes, of the payload buffer.
  * @auxiliary_size:           The size, in bytes, of the auxiliary buffer.
@@ -51,19 +51,23 @@
  *                            which the underlying physical block mark appears.
  * @block_mark_bit_offset:    The bit offset into the ECC-based page view at
  *                            which the underlying physical block mark appears.
+ * @ecc_for_meta:             The flag to indicate if there is a dedicate ecc
+ *                            for meta.
  */
 struct bch_geometry {
 	unsigned int  gf_len;
 	unsigned int  ecc_strength;
 	unsigned int  page_size;
 	unsigned int  metadata_size;
-	unsigned int  ecc_chunk_size;
+	unsigned int  ecc_chunk0_size;
+	unsigned int  ecc_chunkn_size;
 	unsigned int  ecc_chunk_count;
 	unsigned int  payload_size;
 	unsigned int  auxiliary_size;
 	unsigned int  auxiliary_status_offset;
 	unsigned int  block_mark_byte_offset;
 	unsigned int  block_mark_bit_offset;
+	unsigned int  ecc_for_meta; /* ECC for meta data */
 };
 
 /**
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 49f81ca..d7ea954 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2900,6 +2900,7 @@
 	}
 
 	phy_disconnect(fep->phy_dev);
+	fep->phy_dev = NULL;
 
 	fec_enet_clk_enable(ndev, false);
 	pm_qos_remove_request(&ndev->pm_qos_req);
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
index cb19c83..ede0750 100644
--- a/drivers/rtc/rtc-snvs.c
+++ b/drivers/rtc/rtc-snvs.c
@@ -267,7 +267,11 @@
 	value = readl(snvs_base + SNVS_LPCR);
 	/* set TOP and DP_EN bit */
 	writel(value | 0x60, snvs_base + SNVS_LPCR);
-	clk_disable(clk_snvs);
+	/*
+	 * Do not turn off snvs clock otherwise PMIC_ON_REQ can't be pulled
+	 * high by press ONOFF. This is design limitation.
+	 */
+	/* clk_disable(clk_snvs); */
 }
 
 static int snvs_rtc_probe(struct platform_device *pdev)
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index f1390168..b69ee35 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -216,7 +216,6 @@
 	struct regulator *reg_lcd;
 	bool wait4vsync;
 	struct completion vsync_complete;
-	ktime_t vsync_nf_timestamp;
 	struct completion flip_complete;
 	int cur_blank;
 	int restore_blank;
@@ -413,7 +412,6 @@
 		writel(CTRL1_VSYNC_EDGE_IRQ_EN,
 			     host->base + LCDC_CTRL1 + REG_CLR);
 		host->wait4vsync = 0;
-		host->vsync_nf_timestamp = ktime_get();
 		complete(&host->vsync_complete);
 	}
 
@@ -870,16 +868,7 @@
 
 	switch (cmd) {
 	case MXCFB_WAIT_FOR_VSYNC:
-		{
-			long long timestamp;
-			struct mxsfb_info *host = to_imxfb_host(fb_info);
-			ret = mxsfb_wait_for_vsync(fb_info);
-			timestamp = ktime_to_ns(host->vsync_nf_timestamp);
-			if ((ret == 0) && copy_to_user((void *)arg,
-				&timestamp, sizeof(timestamp))) {
-			    ret = -EFAULT;
-			}
-		}
+		ret = mxsfb_wait_for_vsync(fb_info);
 		break;
 	default:
 		break;
@@ -963,13 +952,13 @@
 		host->base + LCDC_CTRL1 + REG_SET);
 
 	ret = wait_for_completion_timeout(&host->flip_complete, HZ / 2);
-	if (ret < 0) {
+	if (!ret) {
 		dev_err(fb_info->device,
 			"mxs wait for pan flip timeout\n");
-		ret = -ETIMEDOUT;
+		return -ETIMEDOUT;
 	}
 
-	return ret;
+	return 0;
 }
 
 static int mxsfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 66aec0c..bc26852 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -3140,9 +3140,67 @@
 };
 
 #ifdef CONFIG_PM
+static void wm8994_store_context(struct wm8994 *wm8994)
+{
+	struct device *dev = wm8994->dev;
+	int ret;
+
+	/* Disable LDO pulldowns while the device is suspended if we
+	 * don't know that something will be driving them. */
+	if (!wm8994->ldo_ena_always_driven)
+		wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
+				WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
+				WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD);
+
+	/* Explicitly put the device into reset in case regulators
+	 * don't get disabled in order to ensure consistent restart.
+	 */
+	wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET,
+			 wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET));
+
+	regcache_mark_dirty(wm8994->regmap);
+
+	/* Restore GPIO registers to prevent problems with mismatched
+	 * pin configurations.
+	 */
+	ret = regcache_sync_region(wm8994->regmap, WM8994_GPIO_1,
+				   WM8994_GPIO_11);
+	if (ret != 0)
+		dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);
+
+	/* In case one of the GPIOs is used as a wake input. */
+	ret = regcache_sync_region(wm8994->regmap,
+				   WM8994_INTERRUPT_STATUS_1_MASK,
+				   WM8994_INTERRUPT_STATUS_1_MASK);
+	if (ret != 0)
+		dev_err(dev, "Failed to restore interrupt mask: %d\n", ret);
+
+	regcache_cache_only(wm8994->regmap, true);
+}
+
+static int wm8994_load_context(struct wm8994 *wm8994)
+{
+	struct device *dev = wm8994->dev;
+	int ret;
+
+	regcache_cache_only(wm8994->regmap, false);
+	ret = regcache_sync(wm8994->regmap);
+	if (ret != 0) {
+		dev_err(dev, "Failed to restore register map: %d\n", ret);
+		return ret;
+	}
+
+	/* Disable LDO pulldowns while the device is active */
+	wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
+			WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD, 0);
+
+	return 0;
+}
+
 static int wm8994_codec_suspend(struct snd_soc_codec *codec)
 {
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994 *control = wm8994->wm8994;
 	int i, ret;
 
 	for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
@@ -3154,16 +3212,24 @@
 				 i + 1, ret);
 	}
 
-	wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
+	wm8994_store_context(control);
 
+	wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
 	return 0;
 }
 
 static int wm8994_codec_resume(struct snd_soc_codec *codec)
 {
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994 *control = wm8994->wm8994;
 	int i, ret;
 
+	ret = wm8994_load_context(control);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to load context: %d\n", ret);
+		return ret;
+	}
+
 	for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
 		if (!wm8994->fll_suspend[i].out)
 			continue;