msm: lpm: Alter the voting mechanism for lpm drivers

Currently the power management drivers monitor the sleep votes received
for certain system wide resources such as system clock and digital voltage
rail. By knowing the sleep vote and the available sleep time , latency
requests the low power management drivers (lpm_resources module) can alter
the sleep votes for those resources during RPM notified sleep modes.

Changing this method because this method requires a new low power level be
added for each combination of the system wide resources being monitored
and that each level be characterized (latency, power etc), this method is
not very scalable as the number of system resources being monitored by the
low power management driver increases. But most of all the decisions on
whether there is enough sleep time to enter these system wide sleep modes
(residency decisions) need to be made at RPM.

This change will remove the lpm_resources module altogether and remove all
low power levels beyond those pertaining L2 cache at lpm_levels.

CRs-Fixed: 490824
Change-Id: I255b696851074dcf7bed40b648c0eb3c5c4d0d6d
Signed-off-by: Girish Mahadevan <girishm@codeaurora.org>
diff --git a/arch/arm/boot/dts/msm8226-pm.dtsi b/arch/arm/boot/dts/msm8226-pm.dtsi
index 0fc6af4..ef0a55e 100644
--- a/arch/arm/boot/dts/msm8226-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-pm.dtsi
@@ -101,62 +101,16 @@
 				50 f0 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
 	};
 
-	qcom,lpm-resources {
-		compatible = "qcom,lpm-resources";
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		qcom,lpm-resources@0 {
-			reg = <0x0>;
-			qcom,name = "vdd-dig";
-			qcom,type = <0x61706d73>;	/* "smpa" */
-			qcom,id = <0x01>;
-			qcom,key = <0x6e726f63>;	/* "corn" */
-			qcom,init-value = <3>;		/* SVS SOC */
-		};
-
-		qcom,lpm-resources@1 {
-			reg = <0x1>;
-			qcom,name = "vdd-mem";
-			qcom,type = <0x616F646C>;	/* "ldoa" */
-			qcom,id = <0x03>;
-			qcom,key = <0x6e726f63>;	/* "corn" */
-			qcom,init-value = <3>;		/* SVS SOC */
-		};
-
-		qcom,lpm-resources@2 {
-			reg = <0x2>;
-			qcom,name = "pxo";
-			qcom,type = <0x306b6c63>;	/* "clk0" */
-			qcom,id = <0x00>;
-			qcom,key = <0x62616e45>;	/* "Enab" */
-			qcom,init-value = "xo_on";
-		};
-
-		qcom,lpm-resources@3 {
-			reg = <0x3>;
-			qcom,name = "l2";
-			qcom,local-resource-type;
-			qcom,init-value = "l2_cache_active";
-		};
-	};
-
 	qcom,lpm-levels {
 		compatible = "qcom,lpm-levels";
+		qcom,default-l2-state = "l2_cache_active";
 		#address-cells = <1>;
 		#size-cells = <0>;
 
 		qcom,lpm-level@0 {
 			reg = <0x0>;
 			qcom,mode = "wfi";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
 			qcom,latency-us = <1>;
 			qcom,ss-power = <784>;
 			qcom,energy-overhead = <190000>;
@@ -166,14 +120,7 @@
 		qcom,lpm-level@1 {
 			reg = <0x1>;
 			qcom,mode = "standalone_pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
 			qcom,latency-us = <3000>;
 			qcom,ss-power = <725>;
 			qcom,energy-overhead = <99500>;
@@ -183,15 +130,8 @@
 		qcom,lpm-level@2 {
 			reg = <0x2>;
 			qcom,mode = "pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_retention";
-			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
-			qcom,latency-us = <8000>;
+			qcom,latency-us = <20000>;
 			qcom,ss-power = <138>;
 			qcom,energy-overhead = <1208400>;
 			qcom,time-overhead = <9200>;
@@ -200,64 +140,12 @@
 		qcom,lpm-level@3 {
 			reg = <0x3>;
 			qcom,mode = "pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <4>; /* NORMAL */
-			qcom,vdd-mem-lower-bound = <3>;  /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <4>;  /* NORMAL */
-			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
-			qcom,latency-us = <9000>;
+			qcom,latency-us = <30000>;
 			qcom,ss-power = <110>;
 			qcom,energy-overhead = <1250300>;
 			qcom,time-overhead = <9500>;
 		};
-
-		qcom,lpm-level@4 {
-			reg = <0x4>;
-			qcom,mode = "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,latency-us = <16300>;
-			qcom,ss-power = <63>;
-			qcom,energy-overhead = <2128000>;
-			qcom,time-overhead = <24200>;
-		};
-
-		qcom,lpm-level@5 {
-			reg = <0x5>;
-			qcom,mode = "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <4>; /* NORMAL */
-			qcom,vdd-mem-lower-bound = <3>;  /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <4>;  /* NORMAL */
-			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
-			qcom,latency-us = <24000>;
-			qcom,ss-power = <10>;
-			qcom,energy-overhead = <3202600>;
-			qcom,time-overhead = <33000>;
-		};
-
-		qcom,lpm-level@6 {
-			reg = <0x6>;
-			qcom,mode = "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <3>; /* SVS SOC */
-			qcom,vdd-mem-lower-bound = <1>; /* RETENTION */
-			qcom,vdd-dig-upper-bound = <3>; /* SVS SOC */
-			qcom,vdd-dig-lower-bound = <1>; /* RETENTION */
-			qcom,latency-us = <26000>;
-			qcom,ss-power = <2>;
-			qcom,energy-overhead = <4252000>;
-			qcom,time-overhead = <38000>;
-		};
 	};
 
 	qcom,pm-boot {
diff --git a/arch/arm/boot/dts/msm8610-pm.dtsi b/arch/arm/boot/dts/msm8610-pm.dtsi
index c531740..d31a65c 100644
--- a/arch/arm/boot/dts/msm8610-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-pm.dtsi
@@ -101,62 +101,16 @@
 				50 f0 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
 	};
 
-	qcom,lpm-resources {
-		compatible = "qcom,lpm-resources";
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		qcom,lpm-resources@0 {
-			reg = <0x0>;
-			qcom,name = "vdd-dig";
-			qcom,type = <0x61706d73>;	/* "smpa" */
-			qcom,id = <0x01>;
-			qcom,key = <0x6e726f63>;	/* "corn" */
-			qcom,init-value = <3>;		/* SVS SOC */
-		};
-
-		qcom,lpm-resources@1 {
-			reg = <0x1>;
-			qcom,name = "vdd-mem";
-			qcom,type = <0x616F646C>;	/* "ldoa" */
-			qcom,id = <0x03>;
-			qcom,key = <0x6e726f63>;	/* "corn" */
-			qcom,init-value = <3>;		/* SVS SOC */
-		};
-
-		qcom,lpm-resources@2 {
-			reg = <0x2>;
-			qcom,name = "pxo";
-			qcom,type = <0x306b6c63>;	/* "clk0" */
-			qcom,id = <0x00>;
-			qcom,key = <0x62616e45>;	/* "Enab" */
-			qcom,init-value = "xo_on";
-		};
-
-		qcom,lpm-resources@3 {
-			reg = <0x3>;
-			qcom,name = "l2";
-			qcom,local-resource-type;
-			qcom,init-value = "l2_cache_active";
-		};
-	};
-
 	qcom,lpm-levels {
 		compatible = "qcom,lpm-levels";
+		qcom,default-l2-state = "l2_cache_active";
 		#address-cells = <1>;
 		#size-cells = <0>;
 
 		qcom,lpm-level@0 {
 			reg = <0x0>;
 			qcom,mode = "wfi";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
 			qcom,latency-us = <1>;
 			qcom,ss-power = <784>;
 			qcom,energy-overhead = <190000>;
@@ -166,14 +120,7 @@
 		qcom,lpm-level@1 {
 			reg = <0x1>;
 			qcom,mode = "standalone_pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
 			qcom,latency-us = <3000>;
 			qcom,ss-power = <725>;
 			qcom,energy-overhead = <99500>;
@@ -183,15 +130,8 @@
 		qcom,lpm-level@2 {
 			reg = <0x2>;
 			qcom,mode = "pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_retention";
-			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
-			qcom,latency-us = <8000>;
+			qcom,latency-us = <20000>;
 			qcom,ss-power = <138>;
 			qcom,energy-overhead = <1208400>;
 			qcom,time-overhead = <9200>;
@@ -200,64 +140,12 @@
 		qcom,lpm-level@3 {
 			reg = <0x3>;
 			qcom,mode = "pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <4>; /* NORMAL */
-			qcom,vdd-mem-lower-bound = <3>;  /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <4>;  /* NORMAL */
-			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
-			qcom,latency-us = <9000>;
+			qcom,latency-us = <30000>;
 			qcom,ss-power = <110>;
 			qcom,energy-overhead = <1250300>;
 			qcom,time-overhead = <9500>;
 		};
-
-		qcom,lpm-level@4 {
-			reg = <0x4>;
-			qcom,mode = "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,latency-us = <16300>;
-			qcom,ss-power = <63>;
-			qcom,energy-overhead = <2128000>;
-			qcom,time-overhead = <24200>;
-		};
-
-		qcom,lpm-level@5 {
-			reg = <0x5>;
-			qcom,mode = "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <4>; /* NORMAL */
-			qcom,vdd-mem-lower-bound = <3>;  /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <4>;  /* NORMAL */
-			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
-			qcom,latency-us = <24000>;
-			qcom,ss-power = <10>;
-			qcom,energy-overhead = <3202600>;
-			qcom,time-overhead = <33000>;
-		};
-
-		qcom,lpm-level@6 {
-			reg = <0x6>;
-			qcom,mode = "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <3>; /* SVS SOC */
-			qcom,vdd-mem-lower-bound = <1>; /* RETENTION */
-			qcom,vdd-dig-upper-bound = <3>; /* SVS SOC */
-			qcom,vdd-dig-lower-bound = <1>; /* RETENTION */
-			qcom,latency-us = <26000>;
-			qcom,ss-power = <2>;
-			qcom,energy-overhead = <4252000>;
-			qcom,time-overhead = <38000>;
-		};
 	};
 
 	qcom,pm-boot {
diff --git a/arch/arm/boot/dts/msm8974-v1-pm.dtsi b/arch/arm/boot/dts/msm8974-v1-pm.dtsi
index 288a703..7362b64 100644
--- a/arch/arm/boot/dts/msm8974-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-v1-pm.dtsi
@@ -129,64 +129,16 @@
 				50 02 32 50 0f];
 	};
 
-	qcom,lpm-resources {
-		compatible = "qcom,lpm-resources";
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		qcom,lpm-resources@0 {
-			reg = <0x0>;
-			qcom,name = "vdd-dig";
-			qcom,type = <0x62706d73>;	/* "smpb" */
-			qcom,id = <0x02>;
-			qcom,key = <0x6e726f63>;	/* "corn" */
-			qcom,init-value = <6>;		/* Super Turbo */
-		};
-
-		qcom,lpm-resources@1 {
-			reg = <0x1>;
-			qcom,name = "vdd-mem";
-			qcom,type = <0x62706d73>;	/* "smpb" */
-			qcom,id = <0x01>;
-			qcom,key = <0x7675>;		/* "uv" */
-			qcom,init-value = <1050000>;	/* Super Turbo */
-		};
-
-		qcom,lpm-resources@2 {
-			reg = <0x2>;
-			qcom,name = "pxo";
-			qcom,type = <0x306b6c63>;	/* "clk0" */
-			qcom,id = <0x00>;
-			qcom,key = <0x62616e45>;	/* "Enab" */
-			qcom,init-value = "xo_on";
-		};
-
-		qcom,lpm-resources@3 {
-			reg = <0x3>;
-			qcom,name = "l2";
-			qcom,local-resource-type;
-			qcom,init-value = "l2_cache_retention";
-		};
-	};
-
 	qcom,lpm-levels {
 		compatible = "qcom,lpm-levels";
+		qcom,default-l2-state = "l2_cache_retention";
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		qcom,use-qtimer;
-
 		qcom,lpm-level@0 {
 			reg = <0x0>;
 			qcom,mode = "wfi";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
 			qcom,latency-us = <1>;
 			qcom,ss-power = <784>;
 			qcom,energy-overhead = <190000>;
@@ -196,14 +148,7 @@
 		qcom,lpm-level@1 {
 			reg = <0x1>;
 			qcom,mode = "retention";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
 			qcom,latency-us = <75>;
 			qcom,ss-power = <735>;
 			qcom,energy-overhead = <77341>;
@@ -214,14 +159,7 @@
 		qcom,lpm-level@2 {
 			reg = <0x2>;
 			qcom,mode = "standalone_pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
 			qcom,latency-us = <95>;
 			qcom,ss-power = <725>;
 			qcom,energy-overhead = <99500>;
@@ -231,15 +169,8 @@
 		qcom,lpm-level@3 {
 			reg = <0x3>;
 			qcom,mode = "pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_gdhs";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
-			qcom,latency-us = <2000>;
+			qcom,latency-us = <20000>;
 			qcom,ss-power = <138>;
 			qcom,energy-overhead = <1208400>;
 			qcom,time-overhead = <3200>;
@@ -248,79 +179,12 @@
 		qcom,lpm-level@4 {
 			reg = <0x4>;
 			qcom,mode = "pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO  */
-			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
-			qcom,latency-us = <3000>;
+			qcom,latency-us = <30000>;
 			qcom,ss-power = <110>;
 			qcom,energy-overhead = <1250300>;
 			qcom,time-overhead = <3500>;
 		};
-
-		qcom,lpm-level@5 {
-			reg = <0x5>;
-			qcom,mode = "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_gdhs";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,latency-us = <3000>;
-			qcom,ss-power = <68>;
-			qcom,energy-overhead = <1350200>;
-			qcom,time-overhead = <4000>;
-		};
-
-		qcom,lpm-level@6 {
-			reg = <0x6>;
-			qcom,mode = "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,latency-us = <10300>;
-			qcom,ss-power = <63>;
-			qcom,energy-overhead = <2128000>;
-			qcom,time-overhead = <18200>;
-		};
-
-		qcom,lpm-level@7 {
-			reg = <0x7>;
-			qcom,mode= "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <950000>; /* NORMAL */
-			qcom,vdd-mem-lower-bound = <950000>;  /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <4>;  /* NORMAL */
-			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
-			qcom,latency-us = <18000>;
-			qcom,ss-power = <10>;
-			qcom,energy-overhead = <3202600>;
-			qcom,time-overhead = <27000>;
-		};
-
-		qcom,lpm-level@8 {
-			reg = <0x8>;
-			qcom,mode= "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <950000>; /* SVS SOC */
-			qcom,vdd-mem-lower-bound = <675000>; /* RETENTION */
-			qcom,vdd-dig-upper-bound = <3>; /* SVS SOC */
-			qcom,vdd-dig-lower-bound = <1>; /* RETENTION */
-			qcom,latency-us = <20000>;
-			qcom,ss-power = <2>;
-			qcom,energy-overhead = <4252000>;
-			qcom,time-overhead = <32000>;
-		};
 	};
 
 	qcom,pm-boot {
diff --git a/arch/arm/boot/dts/msm8974-v2-pm.dtsi b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
index a162bb7..1235c6e 100644
--- a/arch/arm/boot/dts/msm8974-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
@@ -125,64 +125,16 @@
 				50 02 32 50 0f];
 	};
 
-	qcom,lpm-resources {
-		compatible = "qcom,lpm-resources";
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		qcom,lpm-resources@0 {
-			reg = <0x0>;
-			qcom,name = "vdd-dig";
-			qcom,type = <0x62706d73>;	/* "smpb" */
-			qcom,id = <0x02>;
-			qcom,key = <0x6e726f63>;	/* "corn" */
-			qcom,init-value = <6>;		/* Super Turbo */
-		};
-
-		qcom,lpm-resources@1 {
-			reg = <0x1>;
-			qcom,name = "vdd-mem";
-			qcom,type = <0x62706d73>;	/* "smpb" */
-			qcom,id = <0x01>;
-			qcom,key = <0x7675>;		/* "uv" */
-			qcom,init-value = <1050000>;	/* Super Turbo */
-		};
-
-		qcom,lpm-resources@2 {
-			reg = <0x2>;
-			qcom,name = "pxo";
-			qcom,type = <0x306b6c63>;	/* "clk0" */
-			qcom,id = <0x00>;
-			qcom,key = <0x62616e45>;	/* "Enab" */
-			qcom,init-value = "xo_on";
-		};
-
-		qcom,lpm-resources@3 {
-			reg = <0x3>;
-			qcom,name = "l2";
-			qcom,local-resource-type;
-			qcom,init-value = "l2_cache_retention";
-		};
-	};
-
 	qcom,lpm-levels {
 		compatible = "qcom,lpm-levels";
+		qcom,default-l2-state = "l2_cache_retention";
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		qcom,use-qtimer;
-
 		qcom,lpm-level@0 {
 			reg = <0x0>;
 			qcom,mode = "wfi";
-			qcom,xo = "xo_on";
-			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
+			qcom,l2 = "l2_cache_retention";
 			qcom,latency-us = <1>;
 			qcom,ss-power = <715>;
 			qcom,energy-overhead = <17700>;
@@ -192,14 +144,7 @@
 		qcom,lpm-level@1 {
 			reg = <0x1>;
 			qcom,mode = "retention";
-			qcom,xo = "xo_on";
-			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
+			qcom,l2 = "l2_cache_retention";
 			qcom,latency-us = <35>;
 			qcom,ss-power = <542>;
 			qcom,energy-overhead = <34920>;
@@ -210,14 +155,7 @@
 		qcom,lpm-level@2 {
 			reg = <0x2>;
 			qcom,mode = "standalone_pc";
-			qcom,xo = "xo_on";
-			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
+			qcom,l2 = "l2_cache_retention";
 			qcom,latency-us = <300>;
 			qcom,ss-power = <476>;
 			qcom,energy-overhead = <225300>;
@@ -227,32 +165,19 @@
 		qcom,lpm-level@3 {
 			reg = <0x3>;
 			qcom,mode = "standalone_pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_gdhs";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
-			qcom,latency-us = <300>;
+			qcom,latency-us = <320>;
 			qcom,ss-power = <476>;
 			qcom,energy-overhead = <225300>;
-			qcom,time-overhead = <350>;
+			qcom,time-overhead = <375>;
 		};
 
 		qcom,lpm-level@4 {
 			reg = <0x4>;
 			qcom,mode = "pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_gdhs";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
 			qcom,gpio-detectable;
-			qcom,latency-us = <2817>;
+			qcom,latency-us = <20000>;
 			qcom,ss-power = <163>;
 			qcom,energy-overhead = <1577736>;
 			qcom,time-overhead = <5067>;
@@ -261,64 +186,12 @@
 		qcom,lpm-level@5 {
 			reg = <0x5>;
 			qcom,mode = "pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO  */
-			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
-			qcom,latency-us = <3922>;
+			qcom,latency-us = <30000>;
 			qcom,ss-power = <83>;
 			qcom,energy-overhead = <2274420>;
 			qcom,time-overhead = <6605>;
 		};
-
-		qcom,lpm-level@6 {
-			reg = <0x6>;
-			qcom,mode = "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,latency-us = <4922>;
-			qcom,ss-power = <68>;
-			qcom,energy-overhead = <2568180>;
-			qcom,time-overhead = <8812>;
-		};
-
-		qcom,lpm-level@7 {
-			reg = <0x7>;
-			qcom,mode= "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <950000>; /* NORMAL */
-			qcom,vdd-mem-lower-bound = <950000>;  /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <4>;  /* NORMAL */
-			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
-			qcom,latency-us = <5890>;
-			qcom,ss-power = <60>;
-			qcom,energy-overhead = <2675900>;
-			qcom,time-overhead = <10140>;
-		};
-
-		qcom,lpm-level@8 {
-			reg = <0x8>;
-			qcom,mode= "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <950000>; /* SVS SOC */
-			qcom,vdd-mem-lower-bound = <675000>; /* RETENTION */
-			qcom,vdd-dig-upper-bound = <3>; /* SVS SOC */
-			qcom,vdd-dig-lower-bound = <1>; /* RETENTION */
-			qcom,latency-us = <8500>;
-			qcom,ss-power = <18>;
-			qcom,energy-overhead = <3286600>;
-			qcom,time-overhead = <15760>;
-		};
 	};
 
 	qcom,pm-boot {
diff --git a/arch/arm/boot/dts/msm9625-pm.dtsi b/arch/arm/boot/dts/msm9625-pm.dtsi
index e18e143..7989f2b 100644
--- a/arch/arm/boot/dts/msm9625-pm.dtsi
+++ b/arch/arm/boot/dts/msm9625-pm.dtsi
@@ -28,57 +28,16 @@
 		3e 0f];
 	};
 
-	qcom,lpm-resources {
-		compatible = "qcom,lpm-resources";
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		qcom,lpm-resources@0 {
-			reg = <0x0>;
-			qcom,name = "vdd-dig";
-			qcom,type = <0x616F646C>;       /* "ldoa" */
-			qcom,id = <0x0A>;
-			qcom,key = <0x6e726f63>;	/* "corn" */
-			qcom,init-value = <5>;		/* Super Turbo */
-		};
-
-		qcom,lpm-resources@1 {
-			reg = <0x1>;
-			qcom,name = "vdd-mem";
-			qcom,type = <0x616F646C>;       /* "ldoa" */
-			qcom,id = <0x0C>;
-			qcom,key =  <0x7675>;		/* "uv" */
-			qcom,init-value = <1050000>;	/* Super Turbo */
-		};
-
-		qcom,lpm-resources@2 {
-			reg = <0x2>;
-			qcom,name = "pxo";
-			qcom,type = <0x306b6c63>;	/* "clk0" */
-			qcom,id = <0x00>;
-			qcom,key = <0x62616e45>;	/* "Enab" */
-			qcom,init-value = "xo_on";
-		};
-	};
-
 	qcom,lpm-levels {
 		compatible = "qcom,lpm-levels";
+		qcom,no-l2-saw;
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		qcom,use-qtimer;
-
 		qcom,lpm-level@0 {
 			reg = <0x0>;
 			qcom,mode = "wfi";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
 			qcom,latency-us = <100>;
 			qcom,ss-power = <8000>;
 			qcom,energy-overhead = <100000>;
@@ -88,14 +47,7 @@
 		qcom,lpm-level@1 {
 			reg = <0x1>;
 			qcom,mode = "standalone_pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
 			qcom,latency-us = <2000>;
 			qcom,ss-power = <5000>;
 			qcom,energy-overhead = <60100000>;
@@ -105,15 +57,8 @@
 		qcom,lpm-level@2 {
 			reg = <0x2>;
 			qcom,mode = "pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_gdhs";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
-			qcom,latency-us = <3500>;
+			qcom,latency-us = <20000>;
 			qcom,ss-power = <5000>;
 			qcom,energy-overhead = <60350000>;
 			qcom,time-overhead = <6300>;
@@ -122,66 +67,12 @@
 		qcom,lpm-level@3 {
 			reg = <0x3>;
 			qcom,mode = "pc";
-			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <4>; /* NORMAL */
-			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
-			qcom,irqs-detectable;
-			qcom,gpio-detectable;
-			qcom,latency-us = <4500>;
+			qcom,latency-us = <30000>;
 			qcom,ss-power = <5000>;
 			qcom,energy-overhead = <60350000>;
 			qcom,time-overhead = <7300>;
 		};
-
-		qcom,lpm-level@4 {
-			reg = <0x4>;
-			qcom,mode = "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
-			qcom,irqs-detectable;
-			qcom,latency-us = <6800>;
-			qcom,ss-power = <2000>;
-			qcom,energy-overhead = <71850000>;
-			qcom,time-overhead = <13300>;
-		};
-
-		qcom,lpm-level@5 {
-			reg = <0x5>;
-			qcom,mode = "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <950000>; /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
-			qcom,irqs-detectable;
-			qcom,latency-us = <8000>;
-			qcom,ss-power = <1800>;
-			qcom,energy-overhead = <71950000>;
-			qcom,time-overhead = <15300>;
-		};
-
-		qcom,lpm-level@6 {
-			reg = <0x6>;
-			qcom,mode = "pc";
-			qcom,xo = "xo_off";
-			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <950000>; /* SVS SOC */
-			qcom,vdd-mem-lower-bound = <675000>; /* RETENTION */
-			qcom,vdd-dig-upper-bound = <3>; /* SVS SOC */
-			qcom,vdd-dig-lower-bound = <1>; /* RETENTION */
-			qcom,latency-us = <9800>;
-			qcom,ss-power = <0>;
-			qcom,energy-overhead = <76350000>;
-			qcom,time-overhead = <28300>;
-		};
 	};
 
 	qcom,pm-boot {
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index a8eee29..5a43fb4 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -282,7 +282,6 @@
 	select QMI_ENCDEC
 	select DONT_MAP_HOLE_AFTER_MEMBANK0
 	select MSM_ULTRASOUND_B
-	select MSM_LPM_TEST
 	select MSM_RPM_LOG
 	select ARCH_WANT_KMAP_ATOMIC_FLUSH
 
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 56fb625..8c42b8d 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -331,7 +331,7 @@
 obj-$(CONFIG_MSM_SDIO_SMEM) += sdio_smem.o
 obj-$(CONFIG_MSM_RPM) += rpm.o rpm_resources.o
 obj-$(CONFIG_MSM_LPM_TEST) += test-lpm.o
-obj-$(CONFIG_MSM_RPM_SMD) += rpm-smd.o lpm_levels.o lpm_resources.o
+obj-$(CONFIG_MSM_RPM_SMD) += rpm-smd.o lpm_levels.o
 obj-$(CONFIG_MSM_MPM_OF) += mpm-of.o
 obj-$(CONFIG_MSM_MPM) += mpm.o
 obj-$(CONFIG_MSM_RPM_STATS_LOG) += rpm_stats.o rpm_master_stat.o
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index 0d62b7a..aff2d75 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -51,7 +51,6 @@
 #include "platsmp.h"
 #include "spm.h"
 #include "pm.h"
-#include "lpm_resources.h"
 #include "modem_notifier.h"
 
 static struct memtype_reserve msm8226_reserve_table[] __initdata = {
@@ -116,7 +115,6 @@
 	msm_init_modem_notifier_list();
 	msm_smd_init();
 	msm_rpm_driver_init();
-	msm_lpmrs_module_init();
 	msm_spm_device_init();
 	msm_pm_sleep_status_init();
 	rpm_regulator_smd_driver_init();
diff --git a/arch/arm/mach-msm/board-8610.c b/arch/arm/mach-msm/board-8610.c
index c6c9d14..d175bb4 100644
--- a/arch/arm/mach-msm/board-8610.c
+++ b/arch/arm/mach-msm/board-8610.c
@@ -52,7 +52,6 @@
 #include "platsmp.h"
 #include "spm.h"
 #include "pm.h"
-#include "lpm_resources.h"
 #include "modem_notifier.h"
 
 static struct memtype_reserve msm8610_reserve_table[] __initdata = {
@@ -107,7 +106,6 @@
 	msm_init_modem_notifier_list();
 	msm_smd_init();
 	msm_rpm_driver_init();
-	msm_lpmrs_module_init();
 	msm_spm_device_init();
 	msm_pm_sleep_status_init();
 	rpm_regulator_smd_driver_init();
diff --git a/arch/arm/mach-msm/board-8974.c b/arch/arm/mach-msm/board-8974.c
index 68af757..80a957f 100644
--- a/arch/arm/mach-msm/board-8974.c
+++ b/arch/arm/mach-msm/board-8974.c
@@ -45,8 +45,8 @@
 #include "clock.h"
 #include "devices.h"
 #include "spm.h"
+#include "pm.h"
 #include "modem_notifier.h"
-#include "lpm_resources.h"
 #include "platsmp.h"
 
 
@@ -96,7 +96,6 @@
 	msm_init_modem_notifier_list();
 	msm_smd_init();
 	msm_rpm_driver_init();
-	msm_lpmrs_module_init();
 	msm_pm_sleep_status_init();
 	rpm_regulator_smd_driver_init();
 	msm_spm_device_init();
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index 36ad755..058789a 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -42,7 +42,6 @@
 #include <mach/msm_smem.h>
 #include "clock.h"
 #include "modem_notifier.h"
-#include "lpm_resources.h"
 #include "spm.h"
 
 #define MSM_KERNEL_EBI_SIZE	0x51000
@@ -240,7 +239,6 @@
 	msm_init_modem_notifier_list();
 	msm_smd_init();
 	msm_rpm_driver_init();
-	msm_lpmrs_module_init();
 	rpm_regulator_smd_driver_init();
 	msm_spm_device_init();
 	msm_clock_init(&msm9625_clock_init_data);
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index aa33f2c..4d7c3d4 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -16,19 +16,60 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/cpu.h>
 #include <linux/of.h>
 #include <mach/mpm.h>
-#include "lpm_resources.h"
 #include "pm.h"
 #include "rpm-notifier.h"
-
+#include "spm.h"
+#include "idle.h"
 
 enum {
 	MSM_LPM_LVL_DBG_SUSPEND_LIMITS = BIT(0),
 	MSM_LPM_LVL_DBG_IDLE_LIMITS = BIT(1),
 };
 
-#define MAX_STR_LEN 30
+enum {
+	MSM_SCM_L2_ON = 0,
+	MSM_SCM_L2_OFF = 1,
+	MSM_SCM_L2_GDHS = 3,
+};
+
+struct msm_rpmrs_level {
+	enum msm_pm_sleep_mode sleep_mode;
+	uint32_t l2_cache;
+	bool available;
+	uint32_t latency_us;
+	uint32_t steady_state_power;
+	uint32_t energy_overhead;
+	uint32_t time_overhead_us;
+};
+
+struct lpm_lookup_table {
+	uint32_t modes;
+	const char *mode_name;
+};
+
+static void msm_lpm_level_update(void);
+
+static int msm_lpm_cpu_callback(struct notifier_block *cpu_nb,
+				unsigned long action, void *hcpu);
+
+static struct notifier_block __refdata msm_lpm_cpu_nblk = {
+	.notifier_call = msm_lpm_cpu_callback,
+};
+
+static uint32_t allowed_l2_mode;
+static uint32_t sysfs_dbg_l2_mode = MSM_SPM_L2_MODE_POWER_COLLAPSE;
+static uint32_t default_l2_mode;
+
+static bool no_l2_saw;
+
+static ssize_t msm_lpm_levels_attr_show(
+	struct kobject *kobj, struct kobj_attribute *attr, char *buf);
+static ssize_t msm_lpm_levels_attr_store(struct kobject *kobj,
+	struct kobj_attribute *attr, const char *buf, size_t count);
 
 static int msm_lpm_lvl_dbg_msk;
 
@@ -39,9 +80,54 @@
 static struct msm_rpmrs_level *msm_lpm_levels;
 static int msm_lpm_level_count;
 
-static DEFINE_PER_CPU(uint32_t , msm_lpm_sleep_time);
-static DEFINE_PER_CPU(int , lpm_permitted_level);
-static DEFINE_PER_CPU(struct atomic_notifier_head, lpm_notify_head);
+static struct kobj_attribute lpm_l2_kattr = __ATTR(l2,  S_IRUGO|S_IWUSR,\
+		msm_lpm_levels_attr_show, msm_lpm_levels_attr_store);
+
+static struct attribute *lpm_levels_attr[] = {
+	&lpm_l2_kattr.attr,
+	NULL,
+};
+
+static struct attribute_group lpm_levels_attr_grp = {
+	.attrs = lpm_levels_attr,
+};
+
+/* SYSFS */
+static ssize_t msm_lpm_levels_attr_show(
+	struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	struct kernel_param kp;
+	int rc;
+
+	kp.arg = &sysfs_dbg_l2_mode;
+
+	rc = param_get_uint(buf, &kp);
+
+	if (rc > 0) {
+		strlcat(buf, "\n", PAGE_SIZE);
+		rc++;
+	}
+
+	return rc;
+}
+
+static ssize_t msm_lpm_levels_attr_store(struct kobject *kobj,
+	struct kobj_attribute *attr, const char *buf, size_t count)
+{
+	struct kernel_param kp;
+	unsigned int temp;
+	int rc;
+
+	kp.arg = &temp;
+	rc = param_set_uint(buf, &kp);
+	if (rc)
+		return rc;
+
+	sysfs_dbg_l2_mode = temp;
+	msm_lpm_level_update();
+
+	return count;
+}
 
 static int msm_pm_get_sleep_mode_value(struct device_node *node,
 			const char *key, uint32_t *sleep_mode_val)
@@ -74,8 +160,7 @@
 	if (!ret) {
 		ret = -EINVAL;
 		for (i = 0; i < ARRAY_SIZE(pm_sm_lookup); i++) {
-			if (!strncmp(mode_name, pm_sm_lookup[i].mode_name,
-				MAX_STR_LEN)) {
+			if (!strcmp(mode_name, pm_sm_lookup[i].mode_name)) {
 				*sleep_mode_val = pm_sm_lookup[i].modes;
 				ret = 0;
 				break;
@@ -85,16 +170,61 @@
 	return ret;
 }
 
+static int msm_lpm_set_l2_mode(int sleep_mode)
+{
+	int lpm = sleep_mode;
+	int rc = 0;
+
+	if (no_l2_saw)
+		goto bail_set_l2_mode;
+
+	msm_pm_set_l2_flush_flag(MSM_SCM_L2_ON);
+
+	switch (sleep_mode) {
+	case MSM_SPM_L2_MODE_POWER_COLLAPSE:
+		msm_pm_set_l2_flush_flag(MSM_SCM_L2_OFF);
+		break;
+	case MSM_SPM_L2_MODE_GDHS:
+		msm_pm_set_l2_flush_flag(MSM_SCM_L2_GDHS);
+		break;
+	case MSM_SPM_L2_MODE_RETENTION:
+	case MSM_SPM_L2_MODE_DISABLED:
+		break;
+	default:
+		lpm = MSM_SPM_L2_MODE_DISABLED;
+		break;
+	}
+
+	rc = msm_spm_l2_set_low_power_mode(lpm, true);
+
+	if (rc) {
+		if (rc == -ENXIO)
+			WARN_ON_ONCE(1);
+		else
+			pr_err("%s: Failed to set L2 low power mode %d, ERR %d",
+			__func__, lpm, rc);
+	}
+
+bail_set_l2_mode:
+	return rc;
+}
+
 static void msm_lpm_level_update(void)
 {
-	unsigned int lpm_level;
+	int lpm_level;
 	struct msm_rpmrs_level *level = NULL;
+	uint32_t max_l2_mode;
+	static DEFINE_MUTEX(lpm_lock);
+
+	mutex_lock(&lpm_lock);
+
+	max_l2_mode = min(allowed_l2_mode, sysfs_dbg_l2_mode);
 
 	for (lpm_level = 0; lpm_level < msm_lpm_level_count; lpm_level++) {
 		level = &msm_lpm_levels[lpm_level];
-		level->available =
-			!msm_lpm_level_beyond_limit(&level->rs_limits);
+		level->available = !(level->l2_cache > max_l2_mode);
 	}
+	mutex_unlock(&lpm_lock);
 }
 
 int msm_lpm_enter_sleep(uint32_t sclk_count, void *limits,
@@ -102,13 +232,7 @@
 {
 	int ret = 0;
 	int debug_mask;
-	struct msm_rpmrs_limits *l = (struct msm_rpmrs_limits *)limits;
-	struct msm_lpm_sleep_data sleep_data;
-
-	sleep_data.limits = limits;
-	sleep_data.kernel_sleep = __get_cpu_var(msm_lpm_sleep_time);
-	atomic_notifier_call_chain(&__get_cpu_var(lpm_notify_head),
-		MSM_LPM_STATE_ENTER, &sleep_data);
+	uint32_t l2 = *(uint32_t *)limits;
 
 	if (from_idle)
 		debug_mask = msm_lpm_lvl_dbg_msk &
@@ -118,19 +242,20 @@
 			MSM_LPM_LVL_DBG_SUSPEND_LIMITS;
 
 	if (debug_mask)
-		pr_info("%s(): pxo:%d l2:%d mem:0x%x(0x%x) dig:0x%x(0x%x)\n",
-				__func__, l->pxo, l->l2_cache,
-				l->vdd_mem_lower_bound,
-				l->vdd_mem_upper_bound,
-				l->vdd_dig_lower_bound,
-				l->vdd_dig_upper_bound);
+		pr_info("%s(): l2:%d", __func__, l2);
 
-	ret = msm_lpmrs_enter_sleep(sclk_count, l, from_idle, notify_rpm);
+	ret = msm_lpm_set_l2_mode(l2);
+
 	if (ret) {
-		pr_warn("%s() LPM resources failed to enter sleep\n",
-				__func__);
-		goto bail;
+		if (ret == -ENXIO)
+			ret = 0;
+		else {
+			pr_warn("%s(): Failed to set L2 SPM Mode %d",
+					__func__, l2);
+			goto bail;
+		}
 	}
+
 	if (notify_rpm) {
 		ret = msm_rpm_enter_sleep(debug_mask);
 		if (ret) {
@@ -138,6 +263,8 @@
 					__func__, ret);
 			goto bail;
 		}
+
+		msm_mpm_enter_sleep(sclk_count, from_idle);
 	}
 bail:
 	return ret;
@@ -147,12 +274,12 @@
 		bool notify_rpm, bool collapsed)
 {
 
-	msm_lpmrs_exit_sleep((struct msm_rpmrs_limits *)limits,
-				from_idle, notify_rpm, collapsed);
-	if (notify_rpm)
+	msm_lpm_set_l2_mode(default_l2_mode);
+
+	if (notify_rpm) {
+		msm_mpm_exit_sleep(from_idle);
 		msm_rpm_exit_sleep();
-	atomic_notifier_call_chain(&__get_cpu_var(lpm_notify_head),
-			MSM_LPM_STATE_EXIT, NULL);
+	}
 }
 
 void msm_lpm_show_resources(void)
@@ -161,48 +288,6 @@
 	return;
 }
 
-uint32_t msm_pm_get_pxo(struct msm_rpmrs_limits *limits)
-{
-	return limits->pxo;
-}
-
-uint32_t msm_pm_get_l2_cache(struct msm_rpmrs_limits *limits)
-{
-	return limits->l2_cache;
-}
-
-uint32_t msm_pm_get_vdd_mem(struct msm_rpmrs_limits *limits)
-{
-	return limits->vdd_mem_upper_bound;
-}
-
-uint32_t msm_pm_get_vdd_dig(struct msm_rpmrs_limits *limits)
-{
-	return limits->vdd_dig_upper_bound;
-}
-
-static bool lpm_level_permitted(int cur_level_count)
-{
-	if (__get_cpu_var(lpm_permitted_level) == msm_lpm_level_count + 1)
-		return true;
-	return (__get_cpu_var(lpm_permitted_level) == cur_level_count);
-}
-
-int msm_lpm_register_notifier(int cpu, int level_iter,
-			struct notifier_block *nb, bool is_latency_measure)
-{
-	per_cpu(lpm_permitted_level, cpu) = level_iter;
-	return atomic_notifier_chain_register(&per_cpu(lpm_notify_head,
-			cpu), nb);
-}
-
-int msm_lpm_unregister_notifier(int cpu, struct notifier_block *nb)
-{
-	per_cpu(lpm_permitted_level, cpu) = msm_lpm_level_count + 1;
-	return atomic_notifier_chain_unregister(&per_cpu(lpm_notify_head, cpu),
-				nb);
-}
-
 s32 msm_cpuidle_get_deep_idle_latency(void)
 {
 	int i;
@@ -225,17 +310,26 @@
 	}
 	return best->latency_us - 1;
 }
-static bool msm_lpm_irqs_detectable(struct msm_rpmrs_limits *limits,
-		bool irqs_detectable, bool gpio_detectable)
+
+static int msm_lpm_cpu_callback(struct notifier_block *cpu_nb,
+	unsigned long action, void *hcpu)
 {
-	if (!limits->irqs_detectable)
-		return irqs_detectable;
-
-	if (!limits->gpio_detectable)
-		return gpio_detectable;
-
-	return true;
-
+	switch (action) {
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
+		allowed_l2_mode = default_l2_mode;
+		msm_lpm_level_update();
+		break;
+	case CPU_DEAD_FROZEN:
+	case CPU_DEAD:
+	case CPU_UP_CANCELED:
+	case CPU_UP_CANCELED_FROZEN:
+		if (num_online_cpus() == 1)
+			allowed_l2_mode = MSM_SPM_L2_MODE_POWER_COLLAPSE;
+		msm_lpm_level_update();
+		break;
+	}
+	return NOTIFY_OK;
 }
 
 static void *msm_lpm_lowest_limits(bool from_idle,
@@ -244,24 +338,15 @@
 {
 	unsigned int cpu = smp_processor_id();
 	struct msm_rpmrs_level *best_level = NULL;
+	uint32_t best_level_pwr = 0;
 	uint32_t pwr;
 	int i;
-	int best_level_iter = msm_lpm_level_count + 1;
-	bool irqs_detect = false;
-	bool gpio_detect = false;
 	bool modify_event_timer;
 	uint32_t next_wakeup_us = time_param->sleep_us;
 
 	if (!msm_lpm_levels)
 		return NULL;
 
-	msm_lpm_level_update();
-
-	if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) {
-		irqs_detect = msm_mpm_irqs_detectable(from_idle);
-		gpio_detect = msm_mpm_gpio_irqs_detectable(from_idle);
-	}
-
 	for (i = 0; i < msm_lpm_level_count; i++) {
 		struct msm_rpmrs_level *level = &msm_lpm_levels[i];
 
@@ -293,11 +378,6 @@
 		if (next_wakeup_us <= level->time_overhead_us)
 			continue;
 
-		if ((sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) &&
-			!msm_lpm_irqs_detectable(&level->rs_limits,
-				irqs_detect, gpio_detect))
-				continue;
-
 		if ((MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE == sleep_mode)
 			|| (MSM_PM_SLEEP_MODE_POWER_COLLAPSE == sleep_mode))
 			if (!cpu && msm_rpm_waiting_for_ack())
@@ -318,12 +398,10 @@
 			pwr += level->energy_overhead / next_wakeup_us;
 		}
 
-		if (!best_level || best_level->rs_limits.power[cpu] >= pwr) {
+		if (!best_level || (best_level_pwr >= pwr)) {
 
-			level->rs_limits.latency_us[cpu] = level->latency_us;
-			level->rs_limits.power[cpu] = pwr;
 			best_level = level;
-			best_level_iter = i;
+			best_level_pwr = pwr;
 			if (power)
 				*power = pwr;
 			if (modify_event_timer &&
@@ -336,32 +414,78 @@
 				time_param->modified_time_us = 0;
 		}
 	}
-	if (best_level && !lpm_level_permitted(best_level_iter))
-		best_level = NULL;
-	else
-		per_cpu(msm_lpm_sleep_time, cpu) =
-			time_param->modified_time_us ?
-			time_param->modified_time_us : time_param->sleep_us;
 
-	return best_level ? &best_level->rs_limits : NULL;
+	return best_level ? &best_level->l2_cache : NULL;
 }
 
-static struct lpm_test_platform_data lpm_test_pdata;
-
-static struct platform_device msm_lpm_test_device = {
-	.name		= "lpm_test",
-	.id		= -1,
-	.dev		= {
-		.platform_data = &lpm_test_pdata,
-	},
-};
-
 static struct msm_pm_sleep_ops msm_lpm_ops = {
 	.lowest_limits = msm_lpm_lowest_limits,
 	.enter_sleep = msm_lpm_enter_sleep,
 	.exit_sleep = msm_lpm_exit_sleep,
 };
 
+static int msm_lpm_get_l2_cache_value(struct device_node *node,
+			char *key, uint32_t *l2_val)
+{
+	int i;
+	struct lpm_lookup_table l2_mode_lookup[] = {
+		{MSM_SPM_L2_MODE_POWER_COLLAPSE, "l2_cache_pc"},
+		{MSM_SPM_L2_MODE_GDHS, "l2_cache_gdhs"},
+		{MSM_SPM_L2_MODE_RETENTION, "l2_cache_retention"},
+		{MSM_SPM_L2_MODE_DISABLED, "l2_cache_active"}
+	};
+	const char *l2_str;
+	int ret;
+
+	ret = of_property_read_string(node, key, &l2_str);
+	if (!ret) {
+		ret = -EINVAL;
+		for (i = 0; i < ARRAY_SIZE(l2_mode_lookup); i++) {
+			if (!strcmp(l2_str, l2_mode_lookup[i].mode_name)) {
+				*l2_val = l2_mode_lookup[i].modes;
+				ret = 0;
+				break;
+			}
+		}
+	}
+	return ret;
+}
+
+static int __devinit msm_lpm_levels_sysfs_add(void)
+{
+	struct kobject *module_kobj = NULL;
+	struct kobject *low_power_kobj = NULL;
+	int rc = 0;
+
+	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
+	if (!module_kobj) {
+		pr_err("%s: cannot find kobject for module %s\n",
+			__func__, KBUILD_MODNAME);
+		rc = -ENOENT;
+		goto resource_sysfs_add_exit;
+	}
+
+	low_power_kobj = kobject_create_and_add(
+				"enable_low_power", module_kobj);
+	if (!low_power_kobj) {
+		pr_err("%s: cannot create kobject\n", __func__);
+		rc = -ENOMEM;
+		goto resource_sysfs_add_exit;
+	}
+
+	rc = sysfs_create_group(low_power_kobj, &lpm_levels_attr_grp);
+resource_sysfs_add_exit:
+	if (rc) {
+		if (low_power_kobj) {
+			sysfs_remove_group(low_power_kobj,
+						&lpm_levels_attr_grp);
+			kobject_del(low_power_kobj);
+		}
+	}
+
+	return rc;
+}
+
 static int __devinit msm_lpm_levels_probe(struct platform_device *pdev)
 {
 	struct msm_rpmrs_level *levels = NULL;
@@ -372,7 +496,6 @@
 	int ret = 0;
 	uint32_t num_levels = 0;
 	int idx = 0;
-	unsigned int m_cpu = 0;
 
 	for_each_child_of_node(pdev->dev.of_node, node)
 		num_levels++;
@@ -392,49 +515,11 @@
 			goto fail;
 		level->sleep_mode = val;
 
-		key = "qcom,xo";
-		ret = msm_lpm_get_xo_value(node, key, &val);
-		if (ret)
-			goto fail;
-		level->rs_limits.pxo = val;
-
 		key = "qcom,l2";
 		ret = msm_lpm_get_l2_cache_value(node, key, &val);
 		if (ret)
 			goto fail;
-		level->rs_limits.l2_cache = val;
-
-		key = "qcom,vdd-dig-upper-bound";
-		ret = of_property_read_u32(node, key, &val);
-		if (ret)
-			goto fail;
-		level->rs_limits.vdd_dig_upper_bound = val;
-
-		key = "qcom,vdd-dig-lower-bound";
-		ret = of_property_read_u32(node, key, &val);
-		if (ret)
-			goto fail;
-		level->rs_limits.vdd_dig_lower_bound = val;
-
-		key = "qcom,vdd-mem-upper-bound";
-		ret = of_property_read_u32(node, key, &val);
-		if (ret)
-			goto fail;
-		level->rs_limits.vdd_mem_upper_bound = val;
-
-		key = "qcom,vdd-mem-lower-bound";
-		ret = of_property_read_u32(node, key, &val);
-		if (ret)
-			goto fail;
-		level->rs_limits.vdd_mem_lower_bound = val;
-
-		key = "qcom,gpio-detectable";
-		level->rs_limits.gpio_detectable =
-				of_property_read_bool(node, key);
-
-		key = "qcom,irqs-detectable";
-		level->rs_limits.irqs_detectable =
-				of_property_read_bool(node, key);
+		level->l2_cache = val;
 
 		key = "qcom,latency-us";
 		ret = of_property_read_u32(node, key, &val);
@@ -463,22 +548,33 @@
 		level->available = true;
 	}
 
+	node = pdev->dev.of_node;
+	key = "qcom,no-l2-saw";
+	no_l2_saw = of_property_read_bool(node, key);
+
 	msm_lpm_levels = levels;
 	msm_lpm_level_count = idx;
 
-	lpm_test_pdata.msm_lpm_test_levels = msm_lpm_levels;
-	lpm_test_pdata.msm_lpm_test_level_count = msm_lpm_level_count;
-	key = "qcom,use-qtimer";
-	lpm_test_pdata.use_qtimer =
-			of_property_read_bool(pdev->dev.of_node, key);
+	if (num_online_cpus() == 1)
+		allowed_l2_mode = MSM_SPM_L2_MODE_POWER_COLLAPSE;
 
-	for_each_possible_cpu(m_cpu)
-		per_cpu(lpm_permitted_level, m_cpu) =
-					msm_lpm_level_count + 1;
+	/* Do the following two steps only if L2 SAW is present */
+	if (!no_l2_saw) {
+		key = "qcom,default-l2-state";
+		if (msm_lpm_get_l2_cache_value(node, key, &default_l2_mode))
+			goto fail;
 
-	platform_device_register(&msm_lpm_test_device);
+		if (msm_lpm_levels_sysfs_add())
+			goto fail;
+		register_hotcpu_notifier(&msm_lpm_cpu_nblk);
+		msm_pm_set_l2_flush_flag(0);
+	} else {
+		msm_pm_set_l2_flush_flag(1);
+		default_l2_mode = MSM_SPM_L2_MODE_POWER_COLLAPSE;
+	}
+
+	msm_lpm_level_update();
 	msm_pm_set_sleep_ops(&msm_lpm_ops);
-
 	return 0;
 fail:
 	pr_err("%s: Error in name %s key %s\n", __func__, node->full_name, key);
diff --git a/arch/arm/mach-msm/lpm_resources.c b/arch/arm/mach-msm/lpm_resources.c
deleted file mode 100644
index 1d9c539..0000000
--- a/arch/arm/mach-msm/lpm_resources.c
+++ /dev/null
@@ -1,1009 +0,0 @@
-/* Copyright (c) 2012-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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/cpu.h>
-#include <linux/notifier.h>
-#include <linux/hrtimer.h>
-#include <linux/tick.h>
-#include <mach/mpm.h>
-#include <mach/rpm-smd.h>
-#include <mach/trace_msm_low_power.h>
-#include "spm.h"
-#include "lpm_resources.h"
-#include "rpm-notifier.h"
-#include "idle.h"
-
-
-/*Debug Definitions*/
-enum {
-	MSM_LPMRS_DEBUG_RPM = BIT(0),
-	MSM_LPMRS_DEBUG_PXO = BIT(1),
-	MSM_LPMRS_DEBUG_VDD_DIG = BIT(2),
-	MSM_LPMRS_DEBUG_VDD_MEM = BIT(3),
-	MSM_LPMRS_DEBUG_L2 = BIT(4),
-	MSM_LPMRS_DEBUG_LVLS = BIT(5),
-};
-
-static int msm_lpm_debug_mask;
-module_param_named(
-	debug_mask, msm_lpm_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP
-);
-
-static bool msm_lpm_get_rpm_notif = true;
-
-/*Macros*/
-#define MAX_RS_NAME		(16)
-#define MAX_RS_SIZE		(4)
-#define IS_RPM_CTL(rs) \
-	(!strncmp(rs->name, "rpm_ctl", MAX_RS_NAME))
-#define MAX_STR_LEN		30
-
-static bool msm_lpm_beyond_limits_vdd_dig(struct msm_rpmrs_limits *limits);
-static void msm_lpm_aggregate_vdd_dig(struct msm_rpmrs_limits *limits);
-static void msm_lpm_flush_vdd_dig(int notify_rpm);
-static void msm_lpm_notify_vdd_dig(struct msm_rpm_notifier_data
-					*rpm_notifier_cb);
-static int msm_lpm_init_value_vdd_dig(struct device_node *node,
-					char *key, uint32_t *default_value);
-
-static bool msm_lpm_beyond_limits_vdd_mem(struct msm_rpmrs_limits *limits);
-static void msm_lpm_aggregate_vdd_mem(struct msm_rpmrs_limits *limits);
-static void msm_lpm_flush_vdd_mem(int notify_rpm);
-static void msm_lpm_notify_vdd_mem(struct msm_rpm_notifier_data
-					*rpm_notifier_cb);
-static int msm_lpm_init_value_vdd_mem(struct device_node *node,
-					char *key, uint32_t *default_value);
-
-
-static bool msm_lpm_beyond_limits_pxo(struct msm_rpmrs_limits *limits);
-static void msm_lpm_aggregate_pxo(struct msm_rpmrs_limits *limits);
-static void msm_lpm_flush_pxo(int notify_rpm);
-static void msm_lpm_notify_pxo(struct msm_rpm_notifier_data
-					*rpm_notifier_cb);
-static int msm_lpm_init_value_pxo(struct device_node *node,
-				char *key, uint32_t *default_value);
-
-
-static bool msm_lpm_beyond_limits_l2(struct msm_rpmrs_limits *limits);
-static void msm_lpm_flush_l2(int notify_rpm);
-static void msm_lpm_aggregate_l2(struct msm_rpmrs_limits *limits);
-static int msm_lpm_init_value_l2(struct device_node *node,
-				char *key, uint32_t *default_value);
-
-static void msm_lpm_flush_rpm_ctl(int notify_rpm);
-
-static int msm_lpm_rpm_callback(struct notifier_block *rpm_nb,
-				unsigned long action, void *rpm_notif);
-
-static int msm_lpm_cpu_callback(struct notifier_block *cpu_nb,
-				unsigned long action, void *hcpu);
-
-static ssize_t msm_lpm_resource_attr_show(
-	struct kobject *kobj, struct kobj_attribute *attr, char *buf);
-static ssize_t msm_lpm_resource_attr_store(struct kobject *kobj,
-	struct kobj_attribute *attr, const char *buf, size_t count);
-
-
-#define RPMRS_ATTR(_name) \
-	__ATTR(_name, S_IRUGO|S_IWUSR, \
-		msm_lpm_resource_attr_show, msm_lpm_resource_attr_store)
-
-/*Data structures*/
-struct msm_lpm_rs_data {
-	uint32_t type;
-	uint32_t id;
-	uint32_t key;
-	uint32_t value;
-	uint32_t default_value;
-	struct msm_rpm_request *handle;
-};
-
-enum {
-	MSM_LPM_RPM_RS_TYPE = 0,
-	MSM_LPM_LOCAL_RS_TYPE = 1,
-};
-
-enum {
-	MSM_SCM_L2_ON = 0,
-	MSM_SCM_L2_OFF = 1,
-	MSM_SCM_L2_GDHS = 3,
-};
-
-struct msm_lpm_resource {
-	struct msm_lpm_rs_data rs_data;
-	uint32_t sleep_value;
-	char name[MAX_RS_NAME];
-
-	uint32_t  enable_low_power;
-	bool valid;
-
-	bool (*beyond_limits)(struct msm_rpmrs_limits *limits);
-	void (*aggregate)(struct msm_rpmrs_limits *limits);
-	void (*flush)(int notify_rpm);
-	void (*notify)(struct msm_rpm_notifier_data *rpm_notifier_cb);
-	struct kobj_attribute ko_attr;
-	int (*init_value)(struct device_node *node,
-			char *key, uint32_t *default_value);
-};
-
-struct lpm_lookup_table {
-	uint32_t modes;
-	const char *mode_name;
-};
-
-static struct msm_lpm_resource msm_lpm_l2 = {
-	.name = "l2",
-	.beyond_limits = msm_lpm_beyond_limits_l2,
-	.aggregate = msm_lpm_aggregate_l2,
-	.flush = msm_lpm_flush_l2,
-	.notify = NULL,
-	.valid = false,
-	.ko_attr = RPMRS_ATTR(l2),
-	.init_value = msm_lpm_init_value_l2,
-};
-
-static struct msm_lpm_resource msm_lpm_vdd_dig = {
-	.name = "vdd-dig",
-	.beyond_limits = msm_lpm_beyond_limits_vdd_dig,
-	.aggregate = msm_lpm_aggregate_vdd_dig,
-	.flush = msm_lpm_flush_vdd_dig,
-	.notify = msm_lpm_notify_vdd_dig,
-	.valid = false,
-	.ko_attr = RPMRS_ATTR(vdd_dig),
-	.init_value = msm_lpm_init_value_vdd_dig,
-};
-
-static struct msm_lpm_resource msm_lpm_vdd_mem = {
-	.name = "vdd-mem",
-	.beyond_limits = msm_lpm_beyond_limits_vdd_mem,
-	.aggregate = msm_lpm_aggregate_vdd_mem,
-	.flush = msm_lpm_flush_vdd_mem,
-	.notify = msm_lpm_notify_vdd_mem,
-	.valid = false,
-	.ko_attr = RPMRS_ATTR(vdd_mem),
-	.init_value = msm_lpm_init_value_vdd_mem,
-};
-
-static struct msm_lpm_resource msm_lpm_pxo = {
-	.name = "pxo",
-	.beyond_limits = msm_lpm_beyond_limits_pxo,
-	.aggregate = msm_lpm_aggregate_pxo,
-	.flush = msm_lpm_flush_pxo,
-	.notify = msm_lpm_notify_pxo,
-	.valid = false,
-	.ko_attr = RPMRS_ATTR(pxo),
-	.init_value = msm_lpm_init_value_pxo,
-};
-
-static struct msm_lpm_resource *msm_lpm_resources[] = {
-	&msm_lpm_vdd_dig,
-	&msm_lpm_vdd_mem,
-	&msm_lpm_pxo,
-	&msm_lpm_l2,
-};
-
-static struct msm_lpm_resource msm_lpm_rpm_ctl = {
-	.name = "rpm_ctl",
-	.beyond_limits = NULL,
-	.aggregate = NULL,
-	.flush = msm_lpm_flush_rpm_ctl,
-	.valid = true,
-	.ko_attr = RPMRS_ATTR(rpm_ctl),
-};
-
-static struct notifier_block msm_lpm_rpm_nblk = {
-	.notifier_call = msm_lpm_rpm_callback,
-};
-
-static struct notifier_block __refdata msm_lpm_cpu_nblk = {
-	.notifier_call = msm_lpm_cpu_callback,
-};
-
-static DEFINE_SPINLOCK(msm_lpm_sysfs_lock);
-
-/* Attribute Definitions */
-static struct attribute *msm_lpm_attributes[] = {
-	&msm_lpm_vdd_dig.ko_attr.attr,
-	&msm_lpm_vdd_mem.ko_attr.attr,
-	&msm_lpm_pxo.ko_attr.attr,
-	&msm_lpm_l2.ko_attr.attr,
-	NULL,
-};
-
-static struct attribute_group msm_lpm_attribute_group = {
-	.attrs = msm_lpm_attributes,
-};
-
-static struct attribute *msm_lpm_rpm_ctl_attribute[] = {
-	&msm_lpm_rpm_ctl.ko_attr.attr,
-	NULL,
-};
-
-static struct attribute_group msm_lpm_rpm_ctl_attr_group = {
-	.attrs = msm_lpm_rpm_ctl_attribute,
-};
-
-#define GET_RS_FROM_ATTR(attr) \
-	(container_of(attr, struct msm_lpm_resource, ko_attr))
-
-/* RPM */
-static struct msm_rpm_request *msm_lpm_create_rpm_request
-				(uint32_t rsc_type, uint32_t rsc_id)
-{
-	struct msm_rpm_request *handle = NULL;
-
-	handle = msm_rpm_create_request(MSM_RPM_CTX_SLEEP_SET,
-						rsc_type,
-						rsc_id, 1);
-	return handle;
-}
-
-static int msm_lpm_send_sleep_data(struct msm_rpm_request *handle,
-					uint32_t key, uint8_t *value)
-{
-	int ret = 0;
-	int msg_id;
-
-	if (!handle)
-		return ret;
-
-	ret = msm_rpm_add_kvp_data_noirq(handle, key, value, MAX_RS_SIZE);
-
-	if (ret < 0) {
-		pr_err("%s: Error adding kvp data key %u, size %d\n",
-				__func__, key, MAX_RS_SIZE);
-		return ret;
-	}
-
-	msg_id = msm_rpm_send_request_noirq(handle);
-	if (!msg_id) {
-		pr_err("%s: Error sending RPM request key %u, handle 0x%x\n",
-				__func__, key, (unsigned int)handle);
-		ret = -EIO;
-		return ret;
-	}
-
-	ret = msm_rpm_wait_for_ack_noirq(msg_id);
-	if (ret < 0) {
-		pr_err("%s: Couldn't get ACK from RPM for Msg %d Error %d",
-				__func__, msg_id, ret);
-		return ret;
-	}
-	if (msm_lpm_debug_mask & MSM_LPMRS_DEBUG_RPM)
-		pr_info("Rs key %u, value %u, size %d\n", key,
-				*(unsigned int *)value, MAX_RS_SIZE);
-	return ret;
-}
-
-/* RPM Notifier */
-static int msm_lpm_rpm_callback(struct notifier_block *rpm_nb,
-					unsigned long action,
-					void *rpm_notif)
-{
-	int i;
-	struct msm_lpm_resource *rs = NULL;
-	struct msm_rpm_notifier_data *rpm_notifier_cb =
-			(struct msm_rpm_notifier_data *)rpm_notif;
-
-	if (!msm_lpm_get_rpm_notif)
-		return NOTIFY_DONE;
-
-	if (!(rpm_nb && rpm_notif))
-		return NOTIFY_BAD;
-
-	for (i = 0; i < ARRAY_SIZE(msm_lpm_resources); i++) {
-		rs = msm_lpm_resources[i];
-		if (rs && rs->valid && rs->notify)
-			rs->notify(rpm_notifier_cb);
-	}
-
-	return NOTIFY_OK;
-}
-
-/* SYSFS */
-static ssize_t msm_lpm_resource_attr_show(
-	struct kobject *kobj, struct kobj_attribute *attr, char *buf)
-{
-	struct kernel_param kp;
-	unsigned long flags;
-	unsigned int temp;
-	int rc;
-
-	spin_lock_irqsave(&msm_lpm_sysfs_lock, flags);
-	temp = GET_RS_FROM_ATTR(attr)->enable_low_power;
-	spin_unlock_irqrestore(&msm_lpm_sysfs_lock, flags);
-
-	kp.arg = &temp;
-	rc = param_get_uint(buf, &kp);
-
-	if (rc > 0) {
-		strlcat(buf, "\n", PAGE_SIZE);
-		rc++;
-	}
-
-	return rc;
-}
-
-static ssize_t msm_lpm_resource_attr_store(struct kobject *kobj,
-	struct kobj_attribute *attr, const char *buf, size_t count)
-{
-	struct kernel_param kp;
-	unsigned long flags;
-	unsigned int temp;
-	int rc;
-
-	kp.arg = &temp;
-	rc = param_set_uint(buf, &kp);
-	if (rc)
-		return rc;
-
-	spin_lock_irqsave(&msm_lpm_sysfs_lock, flags);
-	GET_RS_FROM_ATTR(attr)->enable_low_power = temp;
-
-	if (IS_RPM_CTL(GET_RS_FROM_ATTR(attr))) {
-		struct msm_lpm_resource *rs = GET_RS_FROM_ATTR(attr);
-		rs->flush(false);
-	}
-
-	spin_unlock_irqrestore(&msm_lpm_sysfs_lock, flags);
-
-	return count;
-}
-
-/* lpm resource handling functions */
-/* Common */
-static void msm_lpm_notify_common(struct msm_rpm_notifier_data *cb,
-				struct msm_lpm_resource *rs)
-{
-	if ((cb->rsc_type == rs->rs_data.type) &&
-		(cb->rsc_id == rs->rs_data.id) &&
-		(cb->key == rs->rs_data.key)) {
-
-		BUG_ON(cb->size > MAX_RS_SIZE);
-
-		if (rs->valid) {
-			if (cb->value) {
-				memcpy(&rs->rs_data.value, cb->value, cb->size);
-				msm_rpm_add_kvp_data_noirq(rs->rs_data.handle,
-						cb->key, cb->value, cb->size);
-			}
-			else
-				rs->rs_data.value = rs->rs_data.default_value;
-
-			if (msm_lpm_debug_mask & MSM_LPMRS_DEBUG_RPM)
-				pr_info("Notification received Rs %s value %u\n",
-						rs->name, rs->rs_data.value);
-		}
-	}
-}
-
-/* L2 */
-static bool msm_lpm_beyond_limits_l2(struct msm_rpmrs_limits *limits)
-{
-	uint32_t l2;
-	bool ret = false;
-	struct msm_lpm_resource *rs = &msm_lpm_l2;
-
-	if (rs->valid) {
-		uint32_t l2_buf = rs->rs_data.value;
-
-		if (rs->enable_low_power == 1)
-			l2 = MSM_LPM_L2_CACHE_GDHS;
-		else if (rs->enable_low_power == 2)
-			l2 = MSM_LPM_L2_CACHE_HSFS_OPEN;
-		else
-			l2 = MSM_LPM_L2_CACHE_ACTIVE ;
-
-		if (l2_buf > l2)
-			l2 = l2_buf;
-		ret = (l2 > limits->l2_cache);
-
-		if (msm_lpm_debug_mask & MSM_LPMRS_DEBUG_L2)
-			pr_info("%s: l2 buf %u, l2 %u, limits %u\n",
-				__func__, l2_buf, l2, limits->l2_cache);
-	}
-	return ret;
-}
-
-static void msm_lpm_aggregate_l2(struct msm_rpmrs_limits *limits)
-{
-	struct msm_lpm_resource *rs = &msm_lpm_l2;
-
-	if (rs->valid)
-		rs->sleep_value = limits->l2_cache;
-	trace_lpm_resources(rs->sleep_value, rs->name);
-}
-
-static void msm_lpm_set_l2_mode(int sleep_mode)
-{
-	int lpm, rc;
-
-	msm_pm_set_l2_flush_flag(MSM_SCM_L2_ON);
-
-	switch (sleep_mode) {
-	case MSM_LPM_L2_CACHE_HSFS_OPEN:
-		lpm = MSM_SPM_L2_MODE_POWER_COLLAPSE;
-		msm_pm_set_l2_flush_flag(MSM_SCM_L2_OFF);
-		break;
-	case MSM_LPM_L2_CACHE_GDHS:
-		lpm = MSM_SPM_L2_MODE_GDHS;
-		msm_pm_set_l2_flush_flag(MSM_SCM_L2_GDHS);
-		break;
-	case MSM_LPM_L2_CACHE_RETENTION:
-		lpm = MSM_SPM_L2_MODE_RETENTION;
-		break;
-	default:
-	case MSM_LPM_L2_CACHE_ACTIVE:
-		lpm = MSM_SPM_L2_MODE_DISABLED;
-		break;
-	}
-
-	rc = msm_spm_l2_set_low_power_mode(lpm, true);
-
-	if (rc < 0)
-		pr_err("%s: Failed to set L2 low power mode %d",
-			__func__, lpm);
-
-	if (msm_lpm_debug_mask & MSM_LPMRS_DEBUG_L2)
-		pr_info("%s: Requesting low power mode %d\n",
-				__func__, lpm);
-}
-
-static int msm_lpm_init_value_l2(struct device_node *node,
-					char *key, uint32_t *default_value)
-{
-	return msm_lpm_get_l2_cache_value(node, key, default_value);
-}
-
-static void msm_lpm_flush_l2(int notify_rpm)
-{
-	struct msm_lpm_resource *rs = &msm_lpm_l2;
-
-	msm_lpm_set_l2_mode(rs->sleep_value);
-}
-
-int msm_lpm_get_l2_cache_value(struct device_node *node,
-			char *key, uint32_t *l2_val)
-{
-	int i;
-	struct lpm_lookup_table l2_mode_lookup[] = {
-		{MSM_LPM_L2_CACHE_HSFS_OPEN, "l2_cache_pc"},
-		{MSM_LPM_L2_CACHE_GDHS, "l2_cache_gdhs"},
-		{MSM_LPM_L2_CACHE_RETENTION, "l2_cache_retention"},
-		{MSM_LPM_L2_CACHE_ACTIVE, "l2_cache_active"}
-	};
-	const char *l2_str;
-	int ret;
-
-	ret = of_property_read_string(node, key, &l2_str);
-	if (!ret) {
-		ret = -EINVAL;
-		for (i = 0; i < ARRAY_SIZE(l2_mode_lookup); i++) {
-			if (!strncmp(l2_str, l2_mode_lookup[i].mode_name,
-				MAX_STR_LEN)) {
-				*l2_val = l2_mode_lookup[i].modes;
-				ret = 0;
-				break;
-			}
-		}
-	}
-	return ret;
-}
-
-/* RPM CTL */
-static void msm_lpm_flush_rpm_ctl(int notify_rpm)
-{
-	struct msm_lpm_resource *rs = &msm_lpm_rpm_ctl;
-	msm_lpm_send_sleep_data(rs->rs_data.handle,
-				rs->rs_data.key,
-				(uint8_t *)&rs->sleep_value);
-}
-
-/*VDD Dig*/
-static bool msm_lpm_beyond_limits_vdd_dig(struct msm_rpmrs_limits *limits)
-{
-	bool ret = true;
-	struct msm_lpm_resource *rs = &msm_lpm_vdd_dig;
-
-	if (rs->valid) {
-		uint32_t vdd_buf = rs->rs_data.value;
-		uint32_t vdd_dig = rs->enable_low_power ? rs->enable_low_power :
-					rs->rs_data.default_value;
-
-		if (vdd_buf > vdd_dig)
-			vdd_dig = vdd_buf;
-
-		ret = (vdd_dig > limits->vdd_dig_upper_bound);
-
-		if (msm_lpm_debug_mask & MSM_LPMRS_DEBUG_VDD_DIG)
-			pr_info("%s:buf %d vdd dig %d limits%d\n",
-				__func__, vdd_buf, vdd_dig,
-				limits->vdd_dig_upper_bound);
-	}
-	return ret;
-}
-
-static int msm_lpm_init_value_vdd_dig(struct device_node *node,
-					char *key, uint32_t *default_value)
-{
-	return of_property_read_u32(node, key, default_value);
-}
-
-static void msm_lpm_aggregate_vdd_dig(struct msm_rpmrs_limits *limits)
-{
-	struct msm_lpm_resource *rs = &msm_lpm_vdd_dig;
-
-	if (rs->valid) {
-		uint32_t vdd_buf = rs->rs_data.value;
-		if (limits->vdd_dig_lower_bound > vdd_buf)
-			rs->sleep_value = limits->vdd_dig_lower_bound;
-		else
-			rs->sleep_value = vdd_buf;
-	}
-	trace_lpm_resources(rs->sleep_value, rs->name);
-}
-
-static void msm_lpm_flush_vdd_dig(int notify_rpm)
-{
-	if (notify_rpm) {
-		struct msm_lpm_resource *rs = &msm_lpm_vdd_dig;
-		msm_lpm_send_sleep_data(rs->rs_data.handle,
-					rs->rs_data.key,
-					(uint8_t *)&rs->sleep_value);
-	}
-}
-
-static void msm_lpm_notify_vdd_dig(struct msm_rpm_notifier_data
-					*rpm_notifier_cb)
-{
-	struct msm_lpm_resource *rs = &msm_lpm_vdd_dig;
-	msm_lpm_notify_common(rpm_notifier_cb, rs);
-}
-
-/*VDD Mem*/
-static bool msm_lpm_beyond_limits_vdd_mem(struct msm_rpmrs_limits *limits)
-{
-	bool ret = true;
-	struct msm_lpm_resource *rs = &msm_lpm_vdd_mem;
-
-	if (rs->valid) {
-		uint32_t vdd_buf = rs->rs_data.value;
-		uint32_t vdd_mem = rs->enable_low_power ? rs->enable_low_power :
-					rs->rs_data.default_value;
-
-		if (vdd_buf > vdd_mem)
-			vdd_mem = vdd_buf;
-
-		ret = (vdd_mem > limits->vdd_mem_upper_bound);
-
-		if (msm_lpm_debug_mask & MSM_LPMRS_DEBUG_VDD_MEM)
-			pr_info("%s:buf %d vdd mem %d limits%d\n",
-				__func__, vdd_buf, vdd_mem,
-				limits->vdd_mem_upper_bound);
-	}
-	return ret;
-}
-
-static void msm_lpm_aggregate_vdd_mem(struct msm_rpmrs_limits *limits)
-{
-	struct msm_lpm_resource *rs = &msm_lpm_vdd_mem;
-
-	if (rs->valid) {
-		uint32_t vdd_buf = rs->rs_data.value;
-		if (limits->vdd_mem_lower_bound > vdd_buf)
-			rs->sleep_value = limits->vdd_mem_lower_bound;
-		else
-			rs->sleep_value = vdd_buf;
-	}
-	trace_lpm_resources(rs->sleep_value, rs->name);
-}
-
-static void msm_lpm_flush_vdd_mem(int notify_rpm)
-{
-	if (notify_rpm) {
-		struct msm_lpm_resource *rs = &msm_lpm_vdd_mem;
-		msm_lpm_send_sleep_data(rs->rs_data.handle,
-					rs->rs_data.key,
-					(uint8_t *)&rs->sleep_value);
-	}
-}
-
-static void msm_lpm_notify_vdd_mem(struct msm_rpm_notifier_data
-					*rpm_notifier_cb)
-{
-	struct msm_lpm_resource *rs = &msm_lpm_vdd_mem;
-	msm_lpm_notify_common(rpm_notifier_cb, rs);
-}
-
-static int msm_lpm_init_value_vdd_mem(struct device_node *node,
-					char *key, uint32_t *default_value)
-{
-	return of_property_read_u32(node, key, default_value);
-}
-
-/*PXO*/
-static bool msm_lpm_beyond_limits_pxo(struct msm_rpmrs_limits *limits)
-{
-	bool ret = true;
-	struct msm_lpm_resource *rs = &msm_lpm_pxo;
-
-	if (rs->valid) {
-		uint32_t pxo_buf = rs->rs_data.value;
-		uint32_t pxo = rs->enable_low_power ? MSM_LPM_PXO_OFF :
-					rs->rs_data.default_value;
-
-		if (pxo_buf > pxo)
-			pxo = pxo_buf;
-
-		ret = (pxo > limits->pxo);
-
-		if (msm_lpm_debug_mask & MSM_LPMRS_DEBUG_PXO)
-			pr_info("%s:pxo buf %d pxo %d limits pxo %d\n",
-					__func__, pxo_buf, pxo, limits->pxo);
-	}
-	return ret;
-}
-
-static void msm_lpm_aggregate_pxo(struct msm_rpmrs_limits *limits)
-{
-	struct msm_lpm_resource *rs = &msm_lpm_pxo;
-
-	if (rs->valid) {
-		uint32_t pxo_buf = rs->rs_data.value;
-		if (limits->pxo > pxo_buf)
-			rs->sleep_value = limits->pxo;
-		else
-			rs->sleep_value = pxo_buf;
-
-		if (msm_lpm_debug_mask & MSM_LPMRS_DEBUG_PXO)
-			pr_info("%s: pxo buf %d sleep value %d\n",
-					__func__, pxo_buf, rs->sleep_value);
-	}
-	trace_lpm_resources(rs->sleep_value, rs->name);
-}
-
-static void msm_lpm_flush_pxo(int notify_rpm)
-{
-	if (notify_rpm) {
-		struct msm_lpm_resource *rs = &msm_lpm_pxo;
-		msm_lpm_send_sleep_data(rs->rs_data.handle,
-					rs->rs_data.key,
-					(uint8_t *)&rs->sleep_value);
-	}
-}
-
-static void msm_lpm_notify_pxo(struct msm_rpm_notifier_data
-					*rpm_notifier_cb)
-{
-	struct msm_lpm_resource *rs = &msm_lpm_pxo;
-	msm_lpm_notify_common(rpm_notifier_cb, rs);
-}
-
-static int msm_lpm_init_value_pxo(struct device_node *node,
-				char *key, uint32_t *default_value)
-{
-	return msm_lpm_get_xo_value(node, key, default_value);
-}
-
-static inline bool msm_lpm_use_mpm(struct msm_rpmrs_limits *limits)
-{
-	return (limits->pxo == MSM_LPM_PXO_OFF);
-}
-
-int msm_lpm_get_xo_value(struct device_node *node,
-			char *key, uint32_t *xo_val)
-{
-	int  i;
-	struct lpm_lookup_table pxo_mode_lookup[] = {
-		{MSM_LPM_PXO_OFF, "xo_off"},
-		{MSM_LPM_PXO_ON, "xo_on"}
-	};
-	const char *xo_str;
-	int ret;
-
-	ret = of_property_read_string(node, key, &xo_str);
-	if (!ret) {
-		ret = -EINVAL;
-		for (i = 0; i < ARRAY_SIZE(pxo_mode_lookup); i++) {
-			if (!strncmp(xo_str, pxo_mode_lookup[i].mode_name,
-				MAX_STR_LEN)) {
-				*xo_val = pxo_mode_lookup[i].modes;
-				ret = 0;
-				break;
-			}
-		}
-	}
-	return ret;
-}
-
-/* LPM levels interface */
-bool msm_lpm_level_beyond_limit(struct msm_rpmrs_limits *limits)
-{
-	int i;
-	struct msm_lpm_resource *rs;
-	bool beyond_limit = false;
-
-	for (i = 0; i < ARRAY_SIZE(msm_lpm_resources); i++) {
-		rs = msm_lpm_resources[i];
-		if (rs->beyond_limits && rs->beyond_limits(limits)) {
-			beyond_limit = true;
-			if (msm_lpm_debug_mask & MSM_LPMRS_DEBUG_LVLS)
-				pr_info("%s: %s beyond limit", __func__,
-						rs->name);
-			break;
-		}
-	}
-
-	return beyond_limit;
-}
-
-int msm_lpmrs_enter_sleep(uint32_t sclk_count, struct msm_rpmrs_limits *limits,
-				bool from_idle, bool notify_rpm)
-{
-	int ret = 0;
-	int i;
-	struct msm_lpm_resource *rs = NULL;
-
-	for (i = 0; i < ARRAY_SIZE(msm_lpm_resources); i++) {
-		rs = msm_lpm_resources[i];
-		if (rs->aggregate)
-			rs->aggregate(limits);
-	}
-
-	msm_lpm_get_rpm_notif = false;
-	for (i = 0; i < ARRAY_SIZE(msm_lpm_resources); i++) {
-		rs = msm_lpm_resources[i];
-		if (rs->valid && rs->flush)
-			rs->flush(notify_rpm);
-	}
-	msm_lpm_get_rpm_notif = true;
-
-	if (notify_rpm)
-		msm_mpm_enter_sleep(sclk_count, from_idle);
-
-	return ret;
-}
-
-void msm_lpmrs_exit_sleep(struct msm_rpmrs_limits *limits,
-		bool from_idle, bool notify_rpm, bool collapsed)
-{
-	if (msm_lpm_use_mpm(limits))
-		msm_mpm_exit_sleep(from_idle);
-
-	if (msm_lpm_l2.valid)
-		msm_lpm_set_l2_mode(msm_lpm_l2.rs_data.default_value);
-}
-
-static int msm_lpm_cpu_callback(struct notifier_block *cpu_nb,
-		unsigned long action, void *hcpu)
-{
-	struct msm_lpm_resource *rs = &msm_lpm_l2;
-	switch (action) {
-	case CPU_UP_PREPARE:
-	case CPU_UP_PREPARE_FROZEN:
-		rs->rs_data.value = rs->rs_data.default_value;
-		break;
-	case CPU_ONLINE_FROZEN:
-	case CPU_ONLINE:
-		if (num_online_cpus() > 1)
-			rs->rs_data.value = rs->rs_data.default_value;
-		break;
-	case CPU_DEAD_FROZEN:
-	case CPU_DEAD:
-		if (num_online_cpus() == 1)
-			rs->rs_data.value = MSM_LPM_L2_CACHE_HSFS_OPEN;
-		break;
-	}
-	return NOTIFY_OK;
-}
-
-/* RPM CTL */
-static int __devinit msm_lpm_init_rpm_ctl(void)
-{
-	struct msm_lpm_resource *rs = &msm_lpm_rpm_ctl;
-
-	rs->rs_data.handle = msm_rpm_create_request(
-				MSM_RPM_CTX_ACTIVE_SET,
-				rs->rs_data.type,
-				rs->rs_data.id, 1);
-	if (!rs->rs_data.handle)
-		return -EIO;
-
-	rs->valid = true;
-	return 0;
-}
-
-static int __devinit msm_lpm_resource_sysfs_add(void)
-{
-	struct kobject *module_kobj = NULL;
-	struct kobject *low_power_kobj = NULL;
-	struct kobject *mode_kobj = NULL;
-	int rc = 0;
-
-	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
-	if (!module_kobj) {
-		pr_err("%s: cannot find kobject for module %s\n",
-			__func__, KBUILD_MODNAME);
-		rc = -ENOENT;
-		goto resource_sysfs_add_exit;
-	}
-
-	low_power_kobj = kobject_create_and_add(
-				"enable_low_power", module_kobj);
-	if (!low_power_kobj) {
-		pr_err("%s: cannot create kobject\n", __func__);
-		rc = -ENOMEM;
-		goto resource_sysfs_add_exit;
-	}
-
-	mode_kobj = kobject_create_and_add(
-				"mode", module_kobj);
-	if (!mode_kobj) {
-		pr_err("%s: cannot create kobject\n", __func__);
-		rc = -ENOMEM;
-		goto resource_sysfs_add_exit;
-	}
-
-	rc = sysfs_create_group(low_power_kobj, &msm_lpm_attribute_group);
-	if (rc) {
-		pr_err("%s: cannot create kobject attribute group\n", __func__);
-		goto resource_sysfs_add_exit;
-	}
-
-	rc = sysfs_create_group(mode_kobj, &msm_lpm_rpm_ctl_attr_group);
-	if (rc) {
-		pr_err("%s: cannot create kobject attribute group\n", __func__);
-		goto resource_sysfs_add_exit;
-	}
-
-resource_sysfs_add_exit:
-	if (rc) {
-		if (low_power_kobj)
-			sysfs_remove_group(low_power_kobj,
-					&msm_lpm_attribute_group);
-		kobject_del(low_power_kobj);
-		kobject_del(mode_kobj);
-	}
-
-	return rc;
-}
-
-late_initcall(msm_lpm_resource_sysfs_add);
-
-static int __devinit msm_lpmrs_probe(struct platform_device *pdev)
-{
-	struct device_node *node = NULL;
-	char *key = NULL;
-	int ret = 0;
-
-	for_each_child_of_node(pdev->dev.of_node, node) {
-		struct msm_lpm_resource *rs = NULL;
-		const char *val;
-		int i;
-		bool local_resource;
-
-		key = "qcom,name";
-		ret = of_property_read_string(node, key, &val);
-		if (ret) {
-			pr_err("Cannot read string\n");
-			goto fail;
-		}
-
-		for (i = 0; i < ARRAY_SIZE(msm_lpm_resources); i++) {
-			char *lpmrs_name = msm_lpm_resources[i]->name;
-			if (!msm_lpm_resources[i]->valid &&
-				!strncmp(val, lpmrs_name, strnlen(lpmrs_name,
-							MAX_RS_NAME))) {
-				rs = msm_lpm_resources[i];
-				break;
-			}
-		}
-
-		if (!rs) {
-			pr_err("LPM resource not found\n");
-			continue;
-		}
-
-		key = "qcom,init-value";
-		ret = rs->init_value(node, key, &rs->rs_data.default_value);
-		if (ret) {
-			pr_err("%s():Failed to read %s\n", __func__, key);
-			goto fail;
-		}
-
-		rs->rs_data.value = rs->rs_data.default_value;
-
-		key = "qcom,local-resource-type";
-		local_resource = of_property_read_bool(node, key);
-
-		if (!local_resource) {
-			key = "qcom,type";
-			ret = of_property_read_u32(node, key,
-					&rs->rs_data.type);
-			if (ret) {
-				pr_err("Failed to read type\n");
-				goto fail;
-			}
-
-			key = "qcom,id";
-			ret = of_property_read_u32(node, key, &rs->rs_data.id);
-			if (ret) {
-				pr_err("Failed to read id\n");
-				goto fail;
-			}
-
-			key = "qcom,key";
-			ret = of_property_read_u32(node, key, &rs->rs_data.key);
-			if (ret) {
-				pr_err("Failed to read key\n");
-				goto fail;
-			}
-
-			rs->rs_data.handle = msm_lpm_create_rpm_request(
-						rs->rs_data.type,
-						rs->rs_data.id);
-
-			if (!rs->rs_data.handle) {
-				pr_err("%s: Failed to allocate handle for %s\n",
-						__func__, rs->name);
-				ret = -1;
-				goto fail;
-			}
-			/* fall through */
-		}
-
-		rs->valid = true;
-	}
-	msm_rpm_register_notifier(&msm_lpm_rpm_nblk);
-	msm_lpm_init_rpm_ctl();
-
-	if (msm_lpm_l2.valid) {
-		register_hotcpu_notifier(&msm_lpm_cpu_nblk);
-		/* For UP mode, set the default to HSFS OPEN*/
-		if (num_possible_cpus() == 1) {
-			msm_lpm_l2.rs_data.default_value =
-					MSM_LPM_L2_CACHE_HSFS_OPEN;
-			msm_lpm_l2.rs_data.value = MSM_LPM_L2_CACHE_HSFS_OPEN;
-		}
-		msm_pm_set_l2_flush_flag(0);
-	} else
-		msm_pm_set_l2_flush_flag(1);
-
-fail:
-	return ret;
-}
-
-static struct of_device_id msm_lpmrs_match_table[] = {
-	{.compatible = "qcom,lpm-resources"},
-	{},
-};
-
-static struct platform_driver msm_lpmrs_driver = {
-	.probe = msm_lpmrs_probe,
-	.driver = {
-		.name = "lpm-resources",
-		.owner = THIS_MODULE,
-		.of_match_table = msm_lpmrs_match_table,
-	},
-};
-
-int __init msm_lpmrs_module_init(void)
-{
-	return platform_driver_register(&msm_lpmrs_driver);
-}
diff --git a/arch/arm/mach-msm/lpm_resources.h b/arch/arm/mach-msm/lpm_resources.h
deleted file mode 100644
index 105cfe6..0000000
--- a/arch/arm/mach-msm/lpm_resources.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/* Copyright (c) 2012-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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __ARCH_ARM_MACH_MSM_LPM_RESOURCES_H
-#define __ARCH_ARM_MACH_MSM_LPM_RESOURCES_H
-
-#include "pm.h"
-#include "test-lpm.h"
-
-enum {
-	MSM_LPM_PXO_OFF,
-	MSM_LPM_PXO_ON
-};
-
-enum {
-	MSM_LPM_L2_CACHE_HSFS_OPEN,
-	MSM_LPM_L2_CACHE_GDHS,
-	MSM_LPM_L2_CACHE_RETENTION,
-	MSM_LPM_L2_CACHE_ACTIVE,
-};
-
-struct msm_rpmrs_limits {
-	uint32_t pxo;
-	uint32_t l2_cache;
-	uint32_t vdd_mem_upper_bound;
-	uint32_t vdd_mem_lower_bound;
-	uint32_t vdd_dig_upper_bound;
-	uint32_t vdd_dig_lower_bound;
-	bool irqs_detectable;
-	bool gpio_detectable;
-
-	uint32_t latency_us[NR_CPUS];
-	uint32_t power[NR_CPUS];
-};
-
-struct msm_rpmrs_level {
-	enum msm_pm_sleep_mode sleep_mode;
-	struct msm_rpmrs_limits rs_limits;
-	bool available;
-	uint32_t latency_us;
-	uint32_t steady_state_power;
-	uint32_t energy_overhead;
-	uint32_t time_overhead_us;
-};
-
-enum {
-	MSM_LPM_STATE_ENTER = 0,
-	MSM_LPM_STATE_EXIT = 1,
-};
-
-#define MSM_PM(field) MSM_LPM_##field
-
-/**
- * msm_pm_get_pxo() -  get the limits for pxo
- * @limits:            pointer to the msm_rpmrs_limits structure
- *
- * This function gets the limits to the resource pxo on
- * 8974
- */
-
-uint32_t msm_pm_get_pxo(struct msm_rpmrs_limits *limits);
-
-/**
- * msm_pm_get_l2_cache() -  get the limits for l2 cache
- * @limits:            pointer to the msm_rpmrs_limits structure
- *
- * This function gets the limits to the resource l2 cache
- * on 8974
- */
-
-uint32_t msm_pm_get_l2_cache(struct msm_rpmrs_limits *limits);
-
-/**
- * msm_pm_get_vdd_mem() -  get the limits for pxo
- * @limits:            pointer to the msm_rpmrs_limits structure
- *
- * This function gets the limits to the resource vdd mem
- * on 8974
- */
-
-uint32_t msm_pm_get_vdd_mem(struct msm_rpmrs_limits *limits);
-
-/**
- * msm_pm_get_vdd_dig() -  get the limits for vdd dig
- * @limits:            pointer to the msm_rpmrs_limits structure
- *
- * This function gets the limits to the resource on 8974
- */
-
-uint32_t msm_pm_get_vdd_dig(struct msm_rpmrs_limits *limits);
-
-/**
- * msm_lpm_get_xo_value() - get the enum value for xo
- * @node		pointer to the device node
- * @key			pxo property key
- * @xo_val		xo enum value
- */
-int msm_lpm_get_xo_value(struct device_node *node,
-			char *key, uint32_t *xo_val);
-
-/**
- * msm_lpm_get_l2_cache_value() - get the enum value for l2 cache
- * @node                pointer to the device node
- * @key                 l2 cache property key
- * @l2_val              l2 mode enum value
- */
-int msm_lpm_get_l2_cache_value(struct device_node *node,
-				char *key, uint32_t *l2_val);
-
-/**
- * struct msm_lpm_sleep_data - abstraction to get sleep data
- * @limits:	pointer to the msm_rpmrs_limits structure
- * @kernel_sleep:	kernel sleep time as decided by the power calculation
- *			algorithm
- *
- * This structure is an abstraction to get the limits and kernel sleep time
- * during enter sleep.
- */
-
-struct msm_lpm_sleep_data {
-	struct msm_rpmrs_limits *limits;
-	uint32_t kernel_sleep;
-};
-
-/**
- * msm_lpm_register_notifier() - register for notifications
- * @cpu:               cpu to debug
- * @level_iter:        low power level index to debug
- * @nb:       notifier block to callback on notifications
- * @is_latency_measure: is it latency measure
- *
- * This function sets the permitted level to the index of the
- * level under test and registers notifier for callback.
- */
-
-int msm_lpm_register_notifier(int cpu, int level_iter,
-		struct notifier_block *nb, bool is_latency_measure);
-
-/**
- * msm_lpm_unregister_notifier() - unregister from notifications
- * @cpu:               cpu to debug
- * @nb:       notifier block to callback on notifications
- *
- * This function sets the permitted level to a value one more than
- * available levels count which indicates that all levels are
- * permitted and it also unregisters notifier for callback.
- */
-
-int msm_lpm_unregister_notifier(int cpu, struct notifier_block *nb);
-
-#ifdef CONFIG_MSM_RPM_SMD
-
-/**
- * msm_lpm_level_beyond_limit() - Check if the resources in a low power level
- * is beyond the limits of the driver votes received for those resources.This
- * function is used by lpm_levels to eliminate any low power level that cannot
- * be entered.
- *
- * @limits: pointer to the resource limits of a low power level.
- *
- * returns true if the resource limits are beyond driver resource votes.
- * false otherwise.
- */
-bool msm_lpm_level_beyond_limit(struct msm_rpmrs_limits *limits);
-
-/**
- * msm_lpmrs_enter_sleep() - Enter sleep flushes the sleep votes of low power
- * resources to the RPM driver, also configure the MPM if needed depending
- * on the low power mode being entered. L2 low power mode is also set in
- * this function.
-
- * @sclk_count: wakeup counter for RPM.
- * @limits: pointer to the resource limits of the low power mode being entered.
- * @from_idle: bool to determine if this call being made as a part of
- *             idle power collapse.
- * @notify_rpm: bool that informs if this is an RPM notified power collapse.
- *
- * returns 0 on success.
- */
-int msm_lpmrs_enter_sleep(uint32_t sclk_count, struct msm_rpmrs_limits *limits,
-	bool from_idle, bool notify_rpm);
-
-/**
- * msm_lpmrs_exit_sleep() - Exit sleep, reset the MPM and L2 mode.
- * @ limits: pointer to resource limits of the most recent low power mode.
- * @from_idle: bool to determine if this call being made as a part of
- *             idle power collapse.
- * @notify_rpm: bool that informs if this is an RPM notified power collapse.
- * @collapsed: bool that informs if the Krait was power collapsed.
- */
-void msm_lpmrs_exit_sleep(struct msm_rpmrs_limits *limits,
-	bool from_idle, bool notify_rpm, bool collapsed);
-/**
- * msm_lpmrs_module_init() - Init function that parses the device tree to
- * get the low power resource attributes and registers with RPM driver for
- * callback notification.
- *
- * returns 0 on success.
- */
-int __init msm_lpmrs_module_init(void);
-
-#else
-static inline bool msm_lpm_level_beyond_limit(struct msm_rpmrs_limits *limits)
-{
-	return true;
-}
-
-static inline int msm_lpmrs_enter_sleep(uint32_t sclk_count,
-	struct msm_rpmrs_limits *limits, bool from_idle, bool notify_rpm)
-{
-	return 0;
-}
-
-static inline void msm_lpmrs_exit_sleep(struct msm_rpmrs_limits *limits,
-	bool from_idle, bool notify_rpm, bool collapsed)
-{
-	return;
-}
-
-static inline int __init msm_lpmrs_module_init(void)
-{
-	return 0;
-}
-#endif /* CONFIG_MSM_RPM_SMD */
-
-#endif