Merge "drivers: soc: qcom: Enable SPM driver"
diff --git a/arch/arm64/boot/dts/qcom/msm8953-pm.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pm.dtsi
new file mode 100644
index 0000000..0cbb0f2
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8953-pm.dtsi
@@ -0,0 +1,267 @@
+/* Copyright (c) 2015-2017, 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 <dt-bindings/msm/pm.h>
+
+&soc {
+	qcom,spm@b1d2000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xb1d2000 0x1000>;
+		reg-names = "saw-base";
+		qcom,name = "system-cci";
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x14>;
+		qcom,saw2-spm-dly= <0x3C102800>;
+		qcom,saw2-spm-ctl = <0xe>;
+		qcom,saw2-avs-ctl = <0x10>;
+		qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3
+					&CPU4 &CPU5 &CPU6 &CPU7>;
+		qcom,vctl-timeout-us = <500>;
+		qcom,vctl-port = <0x0>;
+		qcom,phase-port = <0x1>;
+		qcom,pfm-port = <0x2>;
+	};
+
+	qcom,lpm-levels {
+		compatible = "qcom,lpm-levels";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,pm-cluster@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			label = "system";
+			qcom,psci-mode-shift = <8>;
+			qcom,psci-mode-mask = <0xf>;
+
+			qcom,pm-cluster-level@0 {
+				reg = <0>;
+				label = "system-active";
+				qcom,psci-mode = <0>;
+				qcom,latency-us = <423>;
+				qcom,ss-power = <349>;
+				qcom,energy-overhead = <299110>;
+				qcom,time-overhead = <719>;
+			};
+
+			qcom,pm-cluster-level@1 {
+				reg = <1>;
+				label = "system-wfi";
+				qcom,psci-mode = <1>;
+				qcom,latency-us = <480>;
+				qcom,ss-power = <348>;
+				qcom,energy-overhead = <313989>;
+				qcom,time-overhead = <753>;
+				qcom,min-child-idx = <3>;
+			};
+
+			qcom,pm-cluster-level@2 {
+				reg = <2>;
+				label = "system-pc";
+				qcom,psci-mode = <3>;
+				qcom,latency-us = <11027>;
+				qcom,ss-power = <340>;
+				qcom,energy-overhead = <616035>;
+				qcom,time-overhead = <1495>;
+				qcom,min-child-idx = <3>;
+				qcom,notify-rpm;
+				qcom,is-reset;
+				qcom,reset-level = <LPM_RESET_LVL_PC>;
+			};
+
+			qcom,pm-cluster@0{
+				reg = <0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				label = "pwr";
+				qcom,psci-mode-shift = <4>;
+				qcom,psci-mode-mask = <0xf>;
+
+				qcom,pm-cluster-level@0{
+					reg = <0>;
+					label = "pwr-l2-wfi";
+					qcom,psci-mode = <1>;
+					qcom,latency-us = <180>;
+					qcom,ss-power = <361>;
+					qcom,energy-overhead = <113215>;
+					qcom,time-overhead = <270>;
+				};
+
+				qcom,pm-cluster-level@1{
+					reg = <1>;
+					label = "pwr-l2-retention";
+					qcom,psci-mode = <3>;
+					qcom,latency-us = <188>;
+					qcom,ss-power = <360>;
+					qcom,energy-overhead = <121271>;
+					qcom,time-overhead = <307>;
+					qcom,min-child-idx = <1>;
+					qcom,reset-level =
+						<LPM_RESET_LVL_RET>;
+				};
+
+				qcom,pm-cluster-level@2{
+					reg = <2>;
+					label = "pwr-l2-gdhs";
+					qcom,psci-mode = <4>;
+					qcom,latency-us = <212>;
+					qcom,ss-power = <354>;
+					qcom,energy-overhead = <150748>;
+					qcom,time-overhead = <363>;
+					qcom,min-child-idx = <1>;
+					qcom,reset-level =
+						<LPM_RESET_LVL_GDHS>;
+				};
+
+				qcom,pm-cluster-level@3{
+					reg = <3>;
+					label = "pwr-l2-pc";
+					qcom,psci-mode = <5>;
+					qcom,latency-us = <421>;
+					qcom,ss-power = <350>;
+					qcom,energy-overhead = <277479>;
+					qcom,time-overhead = <690>;
+					qcom,min-child-idx = <1>;
+					qcom,is-reset;
+					qcom,reset-level =
+						<LPM_RESET_LVL_PC>;
+				};
+
+				qcom,pm-cpu {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					qcom,psci-mode-shift = <0>;
+					qcom,psci-mode-mask = <0xf>;
+					qcom,cpu = <&CPU0 &CPU1 &CPU2 &CPU3>;
+
+					qcom,pm-cpu-level@0 {
+						reg = <0>;
+						label = "wfi";
+						qcom,psci-cpu-mode = <1>;
+						qcom,latency-us = <1>;
+						qcom,ss-power = <395>;
+						qcom,energy-overhead = <30424>;
+						qcom,time-overhead = <61>;
+					};
+
+					qcom,pm-cpu-level@1 {
+						reg = <1>;
+						label = "pc";
+						qcom,psci-cpu-mode = <3>;
+						qcom,latency-us = <180>;
+						qcom,ss-power = <361>;
+						qcom,energy-overhead = <113215>;
+						qcom,time-overhead = <270>;
+						qcom,use-broadcast-timer;
+						qcom,is-reset;
+						qcom,reset-level =
+							<LPM_RESET_LVL_PC>;
+					};
+				};
+			};
+
+			qcom,pm-cluster@1{
+				reg = <1>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				label = "perf";
+				qcom,psci-mode-shift = <4>;
+				qcom,psci-mode-mask = <0xf>;
+
+				qcom,pm-cluster-level@0{
+					reg = <0>;
+					label = "perf-l2-wfi";
+					qcom,psci-mode = <1>;
+					qcom,latency-us = <179>;
+					qcom,ss-power = <362>;
+					qcom,energy-overhead = <113242>;
+					qcom,time-overhead = <268>;
+				};
+
+				qcom,pm-cluster-level@1{
+					reg = <1>;
+					label = "perf-l2-retention";
+					qcom,psci-mode = <3>;
+					qcom,latency-us = <186>;
+					qcom,ss-power = <361>;
+					qcom,energy-overhead = <125982>;
+					qcom,time-overhead = <306>;
+					qcom,min-child-idx = <1>;
+					qcom,reset-level =
+						<LPM_RESET_LVL_RET>;
+				};
+
+				qcom,pm-cluster-level@2{
+					reg = <2>;
+					label = "perf-l2-gdhs";
+					qcom,psci-mode = <4>;
+					qcom,latency-us = <210>;
+					qcom,ss-power = <355>;
+					qcom,energy-overhead = <155728>;
+					qcom,time-overhead = <361>;
+					qcom,min-child-idx = <1>;
+					qcom,reset-level =
+						<LPM_RESET_LVL_GDHS>;
+				};
+
+				qcom,pm-cluster-level@3{
+					reg = <3>;
+					label = "perf-l2-pc";
+					qcom,psci-mode = <5>;
+					qcom,latency-us = <423>;
+					qcom,ss-power = <349>;
+					qcom,energy-overhead = <299110>;
+					qcom,time-overhead = <719>;
+					qcom,min-child-idx = <1>;
+					qcom,is-reset;
+					qcom,reset-level =
+						<LPM_RESET_LVL_PC>;
+				};
+
+				qcom,pm-cpu {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					qcom,psci-mode-shift = <0>;
+					qcom,psci-mode-mask = <0xf>;
+					qcom,cpu = <&CPU4 &CPU5 &CPU6 &CPU7>;
+
+					qcom,pm-cpu-level@0 {
+						reg = <0>;
+						label = "wfi";
+						qcom,psci-cpu-mode = <1>;
+						qcom,latency-us = <1>;
+						qcom,ss-power = <397>;
+						qcom,energy-overhead = <30424>;
+						qcom,time-overhead = <61>;
+					};
+
+					qcom,pm-cpu-level@1 {
+						reg = <1>;
+						label = "pc";
+						qcom,psci-cpu-mode = <3>;
+						qcom,latency-us = <179>;
+						qcom,ss-power = <362>;
+						qcom,energy-overhead = <113242>;
+						qcom,time-overhead = <268>;
+						qcom,use-broadcast-timer;
+						qcom,is-reset;
+						qcom,reset-level =
+							<LPM_RESET_LVL_PC>;
+					};
+				};
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index 8b1c607..12b39a9 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -124,6 +124,7 @@
 
 #include "msm8953-pinctrl.dtsi"
 #include "msm8953-cpu.dtsi"
+#include "msm8953-pm.dtsi"
 
 
 &soc {
@@ -559,6 +560,12 @@
 		};
 	};
 
+	rpm_bus: qcom,rpm-smd {
+		compatible = "qcom,rpm-smd";
+		rpm-channel-name = "rpm_requests";
+		rpm-channel-type = <15>; /* SMD_APPS_RPM */
+		};
+
 	qcom,wdt@b017000 {
 		compatible = "qcom,msm-watchdog";
 		reg = <0xb017000 0x1000>;
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 144bb4f..22b7236 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -141,6 +141,22 @@
 	  Say M here if you want to include support for the Qualcomm RPM as a
 	  module. This will build a module called "qcom-smd-rpm".
 
+config MSM_SPM
+        bool "Driver support for SPM and AVS wrapper hardware"
+        help
+          Enables the support for SPM and AVS wrapper hardware on MSMs. SPM
+          hardware is used to manage the processor power during sleep. The
+          driver allows configuring SPM to allow different low power modes for
+          both core and L2.
+
+config MSM_L2_SPM
+        bool "SPM support for L2 cache"
+        help
+          Enable SPM driver support for L2 cache. Some MSM chipsets allow
+          control of L2 cache low power mode with a Subsystem Power manager.
+          Enabling this driver allows configuring L2 SPM for low power modes
+          on supported chipsets.
+
 config QCOM_SCM
 	bool "Secure Channel Manager (SCM) support"
 	default n
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index f59c1f7..6deadc0 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -13,6 +13,7 @@
 obj-$(CONFIG_QCOM_SMD) +=	smd.o
 obj-$(CONFIG_QCOM_SMD_RPM)	+= smd-rpm.o
 obj-$(CONFIG_QCOM_SMEM) +=	smem.o
+obj-$(CONFIG_MSM_SPM) += msm-spm.o spm_devices.o
 obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
 obj-$(CONFIG_QCOM_SMP2P)	+= smp2p.o
 obj-$(CONFIG_QCOM_SMSM)	+= smsm.o
diff --git a/drivers/soc/qcom/msm-spm.c b/drivers/soc/qcom/msm-spm.c
index bffe3f3..3033a4a 100644
--- a/drivers/soc/qcom/msm-spm.c
+++ b/drivers/soc/qcom/msm-spm.c
@@ -170,7 +170,7 @@
 		struct msm_spm_driver_data *dev)
 {
 	if (!dev)
-		return;
+		return -ENODEV;
 
 	msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW_ID);
 	return (dev->reg_shadow[MSM_SPM_REG_SAW_ID] >> 24) & 0xFF;
@@ -198,7 +198,7 @@
 	 * Ensure that vctl_port is always set to 0.
 	 */
 	if (dev->vctl_port) {
-		WARN();
+		__WARN();
 		return;
 	}