Merge "ASoC: wcd9xxx: Export wcd9320_registers.h to user space"
diff --git a/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt b/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt
index 91c2461..e00584f 100644
--- a/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt
+++ b/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt
@@ -3,10 +3,6 @@
 Required properties:
 - compatible :
 	- "qcom,msm-hsuart-v14" to be used for UARTDM Core v1.4
-- cell-index : cell-index to be used as device id to enumerate
-	       TTY based HSUART device as /dev/ttyHS<cell-index>.
-	       Device probe fails if cell-index is not available.
-	       The cell-index value should be from 0 to 255.
 - reg : offset and length of the register set for both the device,
 	uart core and bam core
 - reg-names :
@@ -34,14 +30,15 @@
 
 Example:
 
-	uart7@f995d000 {
+	uart7: uart@f995d000 {
 		compatible = "qcom,msm-hsuart-v14";
-		cell-index = <0>;
 		reg = <0xf995d000 0x1000>,
 		      <0xf9944000 0x5000>;
 		reg-names = "core_mem", "bam_mem";
 		interrupts = <0 113 0>, <0 239 0>;
 		interrupt-names = "core_irq", "bam_irq";
+		qcom,bam-tx-ep-pipe-index = <0>;
+		qcom,bam-rx-ep-pipe-index = <1>;
 	};
 
 Optional properties:
@@ -59,11 +56,21 @@
 - qcom, rx_to_inject : The character to be inserted on wakeup.
 
 
+Aliases :
+An alias may be optionally used to bind the UART device to a TTY device
+(ttyHS<alias_num>) with a given alias number. Aliases are of the form
+uart<n> where <n> is an integer representing the alias number to use.
+On systems with multiple UART devices present, an alias may optionally be
+defined for such devices. The alias value should be from 0 to 255.
+
 Example:
 
+	aliases {
+		uart4 = &uart7; // This device will be enumerated as ttyHS4
+	};
+
 	uart7: uart@f995d000 {
 		compatible = "qcom,msm-hsuart-v14"
-		cell-index = <0>;
 		reg = <0x19c40000 0x1000">,
 		      <0xf9944000 0x5000>;
 		reg-names = "core_mem", "bam_mem";
diff --git a/arch/arm/boot/dts/msm9625-v1.dtsi b/arch/arm/boot/dts/msm9625-v1.dtsi
index 50969b1..6295062 100644
--- a/arch/arm/boot/dts/msm9625-v1.dtsi
+++ b/arch/arm/boot/dts/msm9625-v1.dtsi
@@ -23,14 +23,8 @@
 		compatible = "qcom,msm-imem";
 		reg = <0xfc42b000 0x1000>; /* Address and size of IMEM */
 	};
-
-	qcom,bam_dmux@fc834000 {
-		compatible = "qcom,bam_dmux";
-		reg = <0xfc834000 0x7000>;
-		interrupts = <0 29 1>;
-	};
 };
 
 &ipa_hw {
 	qcom,ipa-hw-ver = <1>; /* IPA h-w revision */
-};
\ No newline at end of file
+};
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index c38ad07..e95d108 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -332,6 +332,12 @@
 		qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50";
 	};
 
+	qcom,bam_dmux@fc834000 {
+		compatible = "qcom,bam_dmux";
+		reg = <0xfc834000 0x7000>;
+		interrupts = <0 29 1>;
+	};
+
 	ipa_hw: qcom,ipa@fd4c0000 {
 		compatible = "qcom,ipa";
 		reg = <0xfd4c0000 0x26000>,
diff --git a/arch/arm/mach-msm/acpuclock-8930ab.c b/arch/arm/mach-msm/acpuclock-8930ab.c
index bcf2451..7ec267b 100644
--- a/arch/arm/mach-msm/acpuclock-8930ab.c
+++ b/arch/arm/mach-msm/acpuclock-8930ab.c
@@ -150,101 +150,140 @@
 	{ }
 };
 
-static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   975000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   975000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),  1000000 },
+static struct acpu_level tbl_PVS0_1700MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),  1000000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),  1000000 },
 	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),  1000000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),  1025000 },
 	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1025000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
-	{ 0, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
-	{ 0, {  1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1262500 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1287500 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1050000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1075000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1100000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1125000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1150000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1175000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1200000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1225000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1250000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1275000 },
 	{ 0, { 0 } }
 };
 
-static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   975000 },
+static struct acpu_level tbl_PVS1_1700MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   975000 },
 	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   975000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),  1000000 },
 	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),  1000000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),  1025000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1025000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
-	{ 0, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
-	{ 0, {  1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1262500 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1287500 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1000000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1025000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1050000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1075000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1100000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1125000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1150000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1175000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1200000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1225000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1250000 },
 	{ 0, { 0 } }
 };
 
-static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
+static struct acpu_level tbl_PVS2_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   975000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   975000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),  1000000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),  1000000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),  1025000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1025000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
-	{ 0, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
-	{ 0, {  1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1262500 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1287500 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   975000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1000000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1025000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1050000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1075000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1100000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1125000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1150000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1175000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1200000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1225000 },
 	{ 0, { 0 } }
 };
 
-/* TODO: Update boost voltage once the pvs data is available */
+static struct acpu_level tbl_PVS3_1700MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   950000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10),  975000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1000000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1025000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1050000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1075000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1100000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1125000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1150000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1175000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1200000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level tbl_PVS4_1700MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10),  950000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10),  975000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1000000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1025000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1050000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1075000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1100000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1125000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1150000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1175000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level tbl_PVS5_1700MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10),  925000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10),  950000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10),  975000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1000000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1025000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1050000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1075000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1100000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1125000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1150000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level tbl_PVS6_1700MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10),  900000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10),  925000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10),  950000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  975000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1000000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1025000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1050000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1075000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1100000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1125000 },
+	{ 0, { 0 } }
+};
+
 static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
-[0][PVS_SLOW]    = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
-[0][PVS_NOMINAL] = { acpu_freq_tbl_nom,  sizeof(acpu_freq_tbl_nom),  25000 },
-[0][PVS_FAST]    = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
+	[0][0] = { tbl_PVS0_1700MHz, sizeof(tbl_PVS0_1700MHz), 0 },
+	[0][1] = { tbl_PVS1_1700MHz, sizeof(tbl_PVS1_1700MHz), 25000 },
+	[0][2] = { tbl_PVS2_1700MHz, sizeof(tbl_PVS2_1700MHz), 25000 },
+	[0][3] = { tbl_PVS3_1700MHz, sizeof(tbl_PVS3_1700MHz), 25000 },
+	[0][4] = { tbl_PVS4_1700MHz, sizeof(tbl_PVS4_1700MHz), 25000 },
+	[0][5] = { tbl_PVS5_1700MHz, sizeof(tbl_PVS5_1700MHz), 25000 },
+	[0][6] = { tbl_PVS6_1700MHz, sizeof(tbl_PVS6_1700MHz), 25000 },
 };
 
 static struct acpuclk_krait_params acpuclk_8930ab_params __initdata = {
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 82fa37b..f115d79 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -2260,6 +2260,13 @@
 	0x0B, 0x00, 0x0f,
 };
 
+static uint8_t spm_retention_with_krait_v3_cmd_sequence[] __initdata = {
+	0x42, 0x1B, 0x00,
+	0x05, 0x03, 0x01, 0x0B,
+	0x00, 0x42, 0x1B,
+	0x0f,
+};
+
 static uint8_t spm_power_collapse_with_rpm[] __initdata = {
 	0x00, 0x24, 0x54, 0x10,
 	0x09, 0x07, 0x01, 0x0B,
@@ -2311,11 +2318,16 @@
 		.cmd = spm_wfi_cmd_sequence,
 	},
 	[1] = {
+		.mode = MSM_SPM_MODE_POWER_RETENTION,
+		.notify_rpm = false,
+		.cmd = spm_retention_cmd_sequence,
+	},
+	[2] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = false,
 		.cmd = spm_power_collapse_without_rpm,
 	},
-	[2] = {
+	[3] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = true,
 		.cmd = spm_power_collapse_with_rpm,
@@ -3713,6 +3725,23 @@
 	cdp_keys_data.nbuttons = ARRAY_SIZE(cdp_keys_pm8917);
 }
 
+static void __init apq8064ab_update_retention_spm(void)
+{
+	int i;
+
+	/* Update the SPM sequences for krait retention on all cores */
+	for (i = 0; i < ARRAY_SIZE(msm_spm_data); i++) {
+		int j;
+		struct msm_spm_platform_data *pdata = &msm_spm_data[i];
+		for (j = 0; j < pdata->num_modes; j++) {
+			if (pdata->modes[j].cmd ==
+					spm_retention_cmd_sequence)
+				pdata->modes[j].cmd =
+				spm_retention_with_krait_v3_cmd_sequence;
+		}
+	}
+}
+
 static void __init apq8064_common_init(void)
 {
 	u32 platform_version = socinfo_get_platform_version();
@@ -3837,11 +3866,16 @@
 	}
 	if (cpu_is_apq8064ab())
 		apq8064ab_update_krait_spm();
+	if (cpu_is_krait_v3()) {
+		msm_pm_set_tz_retention_flag(0);
+		apq8064ab_update_retention_spm();
+	} else {
+		msm_pm_set_tz_retention_flag(1);
+	}
 	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
 	msm_spm_l2_init(msm_spm_l2_data);
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
 	apq8064_epm_adc_init();
-	msm_pm_set_tz_retention_flag(1);
 }
 
 static void __init apq8064_allocate_memory_regions(void)
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index be7675b..a8e117f 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1647,11 +1647,18 @@
 	0x03, 0x0f,
 };
 
+
 static uint8_t spm_retention_cmd_sequence[] __initdata = {
 	0x00, 0x05, 0x03, 0x0D,
 	0x0B, 0x00, 0x0f,
 };
 
+static uint8_t spm_retention_with_krait_v3_cmd_sequence[] __initdata = {
+	0x42, 0x1B, 0x00,
+	0x05, 0x03, 0x01, 0x0B,
+	0x00, 0x42, 0x1B,
+	0x0f,
+};
 static uint8_t spm_power_collapse_without_rpm[] __initdata = {
 	0x00, 0x24, 0x54, 0x10,
 	0x09, 0x03, 0x01,
@@ -1696,11 +1703,16 @@
 		.cmd = spm_wfi_cmd_sequence,
 	},
 	[1] = {
+		.mode = MSM_SPM_MODE_POWER_RETENTION,
+		.notify_rpm = false,
+		.cmd = spm_retention_cmd_sequence,
+	},
+	[2] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = false,
 		.cmd = spm_power_collapse_without_rpm,
 	},
-	[2] = {
+	[3] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = true,
 		.cmd = spm_power_collapse_with_rpm,
@@ -2853,6 +2865,23 @@
 	pdata->uses_pm8917 = true;
 }
 
+static void __init msm8930ab_update_retention_spm(void)
+{
+	int i;
+
+	/* Update the SPM sequences for krait retention on all cores */
+	for (i = 0; i < ARRAY_SIZE(msm_spm_data); i++) {
+		int j;
+		struct msm_spm_platform_data *pdata = &msm_spm_data[i];
+		for (j = 0; j < pdata->num_modes; j++) {
+			if (pdata->modes[j].cmd ==
+					spm_retention_cmd_sequence)
+				pdata->modes[j].cmd =
+				spm_retention_with_krait_v3_cmd_sequence;
+		}
+	}
+}
+
 static void __init msm8930_cdp_init(void)
 {
 	if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
@@ -2925,6 +2954,12 @@
 #endif
 	msm8930_i2c_init();
 	msm8930_init_gpu();
+	if (cpu_is_krait_v3()) {
+		msm_pm_set_tz_retention_flag(0);
+		msm8930ab_update_retention_spm();
+	} else {
+		msm_pm_set_tz_retention_flag(1);
+	}
 	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
 	msm_spm_l2_init(msm_spm_l2_data);
 	msm8930_init_buses();
@@ -2986,7 +3021,6 @@
 		ARRAY_SIZE(msm_slim_devices));
 	change_memory_power = &msm8930_change_memory_power;
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
-	msm_pm_set_tz_retention_flag(1);
 
 	if (PLATFORM_IS_CHARM25())
 		platform_add_devices(mdm_devices, ARRAY_SIZE(mdm_devices));
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index e50229f..6524832 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1736,6 +1736,13 @@
 	0x0B, 0x00, 0x0f,
 };
 
+static uint8_t spm_retention_with_krait_v3_cmd_sequence[] __initdata = {
+	0x42, 0x1B, 0x00,
+	0x05, 0x03, 0x01, 0x0B,
+	0x00, 0x42, 0x1B,
+	0x0f,
+};
+
 static uint8_t spm_power_collapse_without_rpm[] __initdata = {
 	0x00, 0x24, 0x54, 0x10,
 	0x09, 0x03, 0x01,
@@ -1794,12 +1801,20 @@
 		.notify_rpm = false,
 		.cmd = spm_wfi_cmd_sequence,
 	},
+
 	[1] = {
+		.mode = MSM_SPM_MODE_POWER_RETENTION,
+		.notify_rpm = false,
+		.cmd = spm_retention_cmd_sequence,
+	},
+
+	[2] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = false,
 		.cmd = spm_power_collapse_without_rpm,
 	},
-	[2] = {
+
+	[3] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = true,
 		.cmd = spm_power_collapse_with_rpm,
@@ -3398,6 +3413,23 @@
 	}
 }
 
+static void __init msm8960ab_update_retention_spm(void)
+{
+	int i;
+
+	/* Update the SPM sequences for krait retention on all cores */
+	for (i = 0; i < ARRAY_SIZE(msm_spm_data); i++) {
+		int j;
+		struct msm_spm_platform_data *pdata = &msm_spm_data[i];
+		for (j = 0; j < pdata->num_modes; j++) {
+			if (pdata->modes[j].cmd ==
+					spm_retention_cmd_sequence)
+				pdata->modes[j].cmd =
+				spm_retention_with_krait_v3_cmd_sequence;
+		}
+	}
+}
+
 static void __init msm8960_cdp_init(void)
 {
 	if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
@@ -3455,6 +3487,12 @@
 
 	if (cpu_is_msm8960ab())
 		msm8960ab_update_krait_spm();
+	if (cpu_is_krait_v3()) {
+		msm_pm_set_tz_retention_flag(0);
+		msm8960ab_update_retention_spm();
+	} else {
+		msm_pm_set_tz_retention_flag(1);
+	}
 	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
 	msm_spm_l2_init(msm_spm_l2_data);
 
@@ -3520,7 +3558,6 @@
 		mdm_sglte_device.dev.platform_data = &sglte_platform_data;
 		platform_device_register(&mdm_sglte_device);
 	}
-	msm_pm_set_tz_retention_flag(1);
 	ion_adjust_secure_allocation();
 }
 
diff --git a/arch/arm/mach-msm/include/mach/msm_serial_hs.h b/arch/arm/mach-msm/include/mach/msm_serial_hs.h
index cc50955..dd53911 100644
--- a/arch/arm/mach-msm/include/mach/msm_serial_hs.h
+++ b/arch/arm/mach-msm/include/mach/msm_serial_hs.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2010-2013, The Linux Foundation. All rights reserved.
  * Author: Nick Pelly <npelly@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -39,10 +40,10 @@
 	int (*gpio_config)(int);
 	int userid;
 
-	unsigned uart_tx_gpio;
-	unsigned uart_rx_gpio;
-	unsigned uart_cts_gpio;
-	unsigned uart_rfr_gpio;
+	int uart_tx_gpio;
+	int uart_rx_gpio;
+	int uart_cts_gpio;
+	int uart_rfr_gpio;
 	unsigned bam_tx_ep_pipe_index;
 	unsigned bam_rx_ep_pipe_index;
 };
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
index cfd9eae..ef23871 100644
--- a/drivers/misc/tspp.c
+++ b/drivers/misc/tspp.c
@@ -43,11 +43,13 @@
 #include <linux/debugfs.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/string.h>
 
 /*
  * General defines
  */
 #define TSPP_TSIF_INSTANCES            2
+#define TSPP_GPIOS_PER_TSIF            4
 #define TSPP_FILTER_TABLES             3
 #define TSPP_MAX_DEVICES               1
 #define TSPP_NUM_CHANNELS              16
@@ -649,7 +651,9 @@
 }
 
 /*** GPIO functions ***/
-static int tspp_gpios_disable(const struct msm_gpio *table, int size)
+static int tspp_gpios_disable(const struct tspp_tsif_device *tsif_device,
+				const struct msm_gpio *table,
+				int size)
 {
 	int rc = 0;
 	int i;
@@ -659,6 +663,11 @@
 		int tmp;
 		g = table + i;
 
+		/* don't use sync GPIO when not working in mode 2 */
+		if ((tsif_device->mode != TSPP_TSIF_MODE_2) &&
+			(strnstr(g->label, "sync", strlen(g->label)) != NULL))
+			continue;
+
 		tmp = gpio_tlmm_config(GPIO_CFG(GPIO_PIN(g->gpio_cfg),
 			0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
 			GPIO_CFG_DISABLE);
@@ -677,14 +686,22 @@
 	return rc;
 }
 
-static int tspp_gpios_enable(const struct msm_gpio *table, int size)
+static int tspp_gpios_enable(const struct tspp_tsif_device *tsif_device,
+				const struct msm_gpio *table,
+				int size)
 {
 	int rc;
-	int i, j;
+	int i;
 	const struct msm_gpio *g;
 
 	for (i = 0; i < size; i++) {
 		g = table + i;
+
+		/* don't use sync GPIO when not working in mode 2 */
+		if ((tsif_device->mode != TSPP_TSIF_MODE_2) &&
+			(strnstr(g->label, "sync", strlen(g->label)) != NULL))
+			continue;
+
 		rc = gpio_tlmm_config(g->gpio_cfg, GPIO_CFG_ENABLE);
 		if (rc) {
 			pr_err("tspp: gpio_tlmm_config(0x%08x, GPIO_CFG_ENABLE) <%s> failed: %d\n",
@@ -698,26 +715,49 @@
 	}
 	return 0;
 err:
-	for (j = 0; j < i; j++)
-		tspp_gpios_disable(table, j);
+	tspp_gpios_disable(tsif_device, table, i);
 
 	return rc;
 }
 
-static int tspp_start_gpios(struct tspp_device *device)
+
+static int tspp_config_gpios(struct tspp_device *device,
+				enum tspp_source source,
+				int enable)
 {
-	struct msm_tspp_platform_data *pdata =
-		device->pdev->dev.platform_data;
+	const struct msm_gpio *table;
+	struct msm_tspp_platform_data *pdata = device->pdev->dev.platform_data;
+	int num_gpios = (pdata->num_gpios / TSPP_TSIF_INSTANCES);
+	int i = 0;
 
-	return tspp_gpios_enable(pdata->gpios, pdata->num_gpios);
-}
+	if (num_gpios != TSPP_GPIOS_PER_TSIF) {
+		pr_err("tspp %s: unexpected number of GPIOs %d, expected %d\n",
+			__func__, num_gpios, TSPP_GPIOS_PER_TSIF);
+		return -EINVAL;
+	}
 
-static void tspp_stop_gpios(struct tspp_device *device)
-{
-	struct msm_tspp_platform_data *pdata =
-		device->pdev->dev.platform_data;
+	/*
+	 * Note: this code assumes that the GPIO definitions in the
+	 * pdata->gpios table are according to the TSIF instance number,
+	 * i.e., that TSIF0 GPIOs are defined first, then TSIF1 GPIOs etc.
+	 */
+	switch (source) {
+	case TSPP_SOURCE_TSIF0:
+		i = 0;
+		break;
+	case TSPP_SOURCE_TSIF1:
+		i = 1;
+		break;
+	default:
+		pr_err("tspp %s: invalid source\n", __func__);
+		return -EINVAL;
+	}
 
-	tspp_gpios_disable(pdata->gpios, pdata->num_gpios);
+	table = pdata->gpios + (i * num_gpios);
+	if (enable)
+		return tspp_gpios_enable(&device->tsif[i], table, num_gpios);
+	else
+		return tspp_gpios_disable(&device->tsif[i], table, num_gpios);
 }
 
 /*** Clock functions ***/
@@ -1270,6 +1310,10 @@
 
 	switch (source->source) {
 	case TSPP_SOURCE_TSIF0:
+		if (tspp_config_gpios(pdev, channel->src, 1) != 0) {
+			pr_err("tspp: error enabling tsif0 GPIOs\n");
+			return -EBUSY;
+		}
 		/* make sure TSIF0 is running & enabled */
 		if (tspp_start_tsif(&pdev->tsif[0]) != 0) {
 			pr_err("tspp: error starting tsif0");
@@ -1281,6 +1325,10 @@
 		wmb();
 		break;
 	case TSPP_SOURCE_TSIF1:
+		if (tspp_config_gpios(pdev, channel->src, 1) != 0) {
+			pr_err("tspp: error enabling tsif1 GPIOs\n");
+			return -EBUSY;
+		}
 		/* make sure TSIF1 is running & enabled */
 		if (tspp_start_tsif(&pdev->tsif[1]) != 0) {
 			pr_err("tspp: error starting tsif1");
@@ -1332,6 +1380,9 @@
 	switch (channel->src) {
 	case TSPP_SOURCE_TSIF0:
 		tspp_stop_tsif(&pdev->tsif[0]);
+		if (tspp_config_gpios(pdev, channel->src, 0) != 0)
+			pr_err("tspp: error disabling tsif0 GPIOs\n");
+
 		val = readl_relaxed(pdev->base + TSPP_CONTROL);
 		writel_relaxed(val | TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
 			pdev->base + TSPP_CONTROL);
@@ -1339,6 +1390,9 @@
 		break;
 	case TSPP_SOURCE_TSIF1:
 		tspp_stop_tsif(&pdev->tsif[1]);
+		if (tspp_config_gpios(pdev, channel->src, 0) != 0)
+			pr_err("tspp: error disabling tsif0 GPIOs\n");
+
 		val = readl_relaxed(pdev->base + TSPP_CONTROL);
 		writel_relaxed(val | TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
 			pdev->base + TSPP_CONTROL);
@@ -2835,11 +2889,6 @@
 	if (msm_tspp_map_irqs(pdev, device))
 		goto err_irq;
 
-	/* GPIOs */
-	rc = tspp_start_gpios(device);
-	if (rc)
-		goto err_gpio;
-
 	/* power management */
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
@@ -2924,9 +2973,6 @@
 	tspp_debugfs_exit(device);
 	for (i = 0; i < TSPP_TSIF_INSTANCES; i++)
 		tsif_debugfs_exit(&device->tsif[i]);
-
-	tspp_stop_gpios(device);
-err_gpio:
 err_irq:
 	for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
 		if (device->tsif[i].tsif_irq)
@@ -2987,7 +3033,6 @@
 
 	wake_lock_destroy(&device->wake_lock);
 	free_irq(device->tspp_irq, device);
-	tspp_stop_gpios(device);
 
 	iounmap(device->bam_props.virt_addr);
 	iounmap(device->base);
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 6684fc4..fd866e1 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -40,6 +40,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
+#include <linux/atomic.h>
 #include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/clk.h>
@@ -57,6 +58,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
+#include <linux/gpio.h>
 #include <asm/atomic.h>
 #include <asm/irq.h>
 
@@ -2002,6 +2004,100 @@
 	return ("MSM HS UART");
 }
 
+/**
+ * msm_hs_unconfig_uart_gpios: Unconfigures UART GPIOs
+ * @uport: uart port
+ */
+static void msm_hs_unconfig_uart_gpios(struct uart_port *uport)
+{
+	struct platform_device *pdev = to_platform_device(uport->dev);
+	const struct msm_serial_hs_platform_data *pdata =
+					pdev->dev.platform_data;
+
+	if (pdata) {
+		if (gpio_is_valid(pdata->uart_tx_gpio))
+			gpio_free(pdata->uart_tx_gpio);
+		if (gpio_is_valid(pdata->uart_rx_gpio))
+			gpio_free(pdata->uart_rx_gpio);
+		if (gpio_is_valid(pdata->uart_cts_gpio))
+			gpio_free(pdata->uart_cts_gpio);
+		if (gpio_is_valid(pdata->uart_rfr_gpio))
+			gpio_free(pdata->uart_rfr_gpio);
+	} else {
+		pr_err("Error:Pdata is NULL.\n");
+	}
+}
+
+/**
+ * msm_hs_config_uart_gpios - Configures UART GPIOs
+ * @uport: uart port
+ */
+static int msm_hs_config_uart_gpios(struct uart_port *uport)
+{
+	struct platform_device *pdev = to_platform_device(uport->dev);
+	const struct msm_serial_hs_platform_data *pdata =
+					pdev->dev.platform_data;
+	int ret = 0;
+
+	if (pdata) {
+		if (gpio_is_valid(pdata->uart_tx_gpio)) {
+			ret = gpio_request(pdata->uart_tx_gpio,
+							"UART_TX_GPIO");
+			if (unlikely(ret)) {
+				pr_err("gpio request failed for:%d\n",
+					pdata->uart_tx_gpio);
+				goto exit_uart_config;
+			}
+		}
+
+		if (gpio_is_valid(pdata->uart_rx_gpio)) {
+			ret = gpio_request(pdata->uart_rx_gpio,
+							"UART_RX_GPIO");
+			if (unlikely(ret)) {
+				pr_err("gpio request failed for:%d\n",
+					pdata->uart_rx_gpio);
+				goto uart_tx_unconfig;
+			}
+		}
+
+		if (gpio_is_valid(pdata->uart_cts_gpio)) {
+			ret = gpio_request(pdata->uart_cts_gpio,
+							"UART_CTS_GPIO");
+			if (unlikely(ret)) {
+				pr_err("gpio request failed for:%d\n",
+					pdata->uart_cts_gpio);
+				goto uart_rx_unconfig;
+			}
+		}
+
+		if (gpio_is_valid(pdata->uart_rfr_gpio)) {
+			ret = gpio_request(pdata->uart_rfr_gpio,
+							"UART_RFR_GPIO");
+			if (unlikely(ret)) {
+				pr_err("gpio request failed for:%d\n",
+					pdata->uart_rfr_gpio);
+				goto uart_cts_unconfig;
+			}
+		}
+	} else {
+		pr_err("Pdata is NULL.\n");
+		ret = -EINVAL;
+	}
+	return ret;
+
+uart_cts_unconfig:
+	if (gpio_is_valid(pdata->uart_cts_gpio))
+		gpio_free(pdata->uart_cts_gpio);
+uart_rx_unconfig:
+	if (gpio_is_valid(pdata->uart_rx_gpio))
+		gpio_free(pdata->uart_rx_gpio);
+uart_tx_unconfig:
+	if (gpio_is_valid(pdata->uart_tx_gpio))
+		gpio_free(pdata->uart_tx_gpio);
+exit_uart_config:
+	return ret;
+}
+
 /* Called when port is opened */
 static int msm_hs_startup(struct uart_port *uport)
 {
@@ -2035,10 +2131,17 @@
 		return ret;
 	}
 
-	if (pdata && pdata->gpio_config)
-		if (unlikely(pdata->gpio_config(1)))
-			dev_err(uport->dev, "Cannot configure gpios\n");
-
+	if (is_blsp_uart(msm_uport)) {
+		ret = msm_hs_config_uart_gpios(uport);
+		if (ret) {
+			pr_err("Uart GPIO request failed\n");
+			goto deinit_uart_clk;
+		}
+	} else {
+		if (pdata && pdata->gpio_config)
+			if (unlikely(pdata->gpio_config(1)))
+				dev_err(uport->dev, "Cannot configure gpios\n");
+	}
 
 	/* SPS Connect for BAM endpoints */
 	if (is_blsp_uart(msm_uport)) {
@@ -2046,7 +2149,7 @@
 		ret = msm_hs_spsconnect_tx(uport);
 		if (ret) {
 			pr_err("msm_serial_hs: SPS connect failed for TX");
-			goto deinit_uart_clk;
+			goto unconfig_uart_gpios;
 		}
 
 		/* SPS connect for RX */
@@ -2178,6 +2281,9 @@
 sps_disconnect_tx:
 	if (is_blsp_uart(msm_uport))
 		sps_disconnect(sps_pipe_handle_tx);
+unconfig_uart_gpios:
+	if (is_blsp_uart(msm_uport))
+		msm_hs_unconfig_uart_gpios(uport);
 deinit_uart_clk:
 	clk_disable_unprepare(msm_uport->clk);
 	if (msm_uport->pclk)
@@ -2593,9 +2699,13 @@
 	return rc;
 }
 
+#define BLSP_UART_NR	12
+static int deviceid[BLSP_UART_NR] = {0};
+static atomic_t msm_serial_hs_next_id = ATOMIC_INIT(0);
+
 static int __devinit msm_hs_probe(struct platform_device *pdev)
 {
-	int ret = 0;
+	int ret = 0, alias_num = -1;
 	struct uart_port *uport;
 	struct msm_hs_port *msm_uport;
 	struct resource *core_resource;
@@ -2603,7 +2713,6 @@
 	struct resource *resource;
 	int core_irqres, bam_irqres;
 	struct msm_serial_hs_platform_data *pdata = pdev->dev.platform_data;
-	struct device_node *node = pdev->dev.of_node;
 
 	if (pdev->dev.of_node) {
 		dev_dbg(&pdev->dev, "device tree enabled\n");
@@ -2611,8 +2720,32 @@
 		if (IS_ERR(pdata))
 			return PTR_ERR(pdata);
 
-		of_property_read_u32(node, "cell-index",
-					&pdev->id);
+		if (pdev->id == -1) {
+			pdev->id = atomic_inc_return(&msm_serial_hs_next_id)-1;
+			deviceid[pdev->id] = 1;
+		}
+
+		/* Use alias from device tree if present
+		 * Alias is used as an optional property
+		 */
+		alias_num = of_alias_get_id(pdev->dev.of_node, "uart");
+		if (alias_num >= 0) {
+			/* If alias_num is between 0 and 11, check that it not
+			 * equal to previous incremented pdev-ids. If it is
+			 * equal to previous pdev.ids , fail deviceprobe.
+			 */
+			if (alias_num < BLSP_UART_NR) {
+				if (deviceid[alias_num] == 0) {
+					pdev->id = alias_num;
+				} else {
+					pr_err("alias_num=%d already used\n",
+								alias_num);
+					return -EINVAL;
+				}
+			} else {
+				pdev->id = alias_num;
+			}
+		}
 
 		pdev->dev.platform_data = pdata;
 	}
@@ -2991,9 +3124,13 @@
 	if (use_low_power_wakeup(msm_uport))
 		free_irq(msm_uport->wakeup.irq, msm_uport);
 
-	if (pdata && pdata->gpio_config)
-		if (pdata->gpio_config(0))
-			dev_err(uport->dev, "GPIO config error\n");
+	if (is_blsp_uart(msm_uport)) {
+		msm_hs_unconfig_uart_gpios(uport);
+	} else {
+		if (pdata && pdata->gpio_config)
+			if (pdata->gpio_config(0))
+				dev_err(uport->dev, "GPIO config error\n");
+	}
 }
 
 static void __exit msm_serial_hs_exit(void)