Merge "drivers: soc: qcom: handle system sleep activities" into msm-4.8
diff --git a/Documentation/devicetree/bindings/arm/msm/system_pm.txt b/Documentation/devicetree/bindings/arm/msm/system_pm.txt
new file mode 100644
index 0000000..9628d9e
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/system_pm.txt
@@ -0,0 +1,29 @@
+SYSTEM PM
+
+System PM device is a virtual device that handles all CPU subsystem low power
+mode activties. When entering core shutdown, resource state that were requested
+from the processor may be relinquished and set to idle and restored when the
+cores are brought out of sleep.
+
+PROPERTIES
+
+- compatible:
+ Usage: required
+ Value type: <string>
+ Definition: must be "qcom,system-pm".
+
+-mboxes:
+ Usage: optional
+ Value type: <phandle>
+ Definition: phandle the TCS mailbox controller for the CPU subsystem.
+ This property is generally set only for SoCs that use RPMH communication
+ through a mailbox controller.
+
+EXAMPLE
+
+ system_pm {
+ compatible = "qcom,system-pm";
+ mboxes = <&apps_rsc 0>;
+ };
+
+
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index df0ae82..9f5eab9 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -286,6 +286,10 @@
bool "QTI RPMH (h/w accelerators) Communication API"
select MAILBOX
select QTI_RPMH_MBOX
+ select QTI_SYSTEM_PM
help
This option enables RPMH hardware communication for making shared
resource requests on Qualcomm Technologies Inc SoCs.
+
+config QTI_SYSTEM_PM
+ bool
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 9f15745..1e3bf00 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -31,3 +31,4 @@
obj-$(CONFIG_TRACER_PKT) += tracer_pkt.o
obj-$(CONFIG_QCOM_BUS_SCALING) += msm_bus/
obj-$(CONFIG_QTI_RPMH_API) += rpmh.o
+obj-$(CONFIG_QTI_SYSTEM_PM) += system_pm.o
diff --git a/drivers/soc/qcom/system_pm.c b/drivers/soc/qcom/system_pm.c
new file mode 100644
index 0000000..78690d9
--- /dev/null
+++ b/drivers/soc/qcom/system_pm.c
@@ -0,0 +1,87 @@
+/* Copyright (c) 2016, 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/kernel.h>
+#include <linux/platform_device.h>
+
+#include <soc/qcom/rpmh.h>
+
+#define PDC_TIME_VALID_SHIFT 31
+#define PDC_TIME_UPPER_MASK 0xFFFFFF
+
+static struct rpmh_client *rpmh_client;
+
+static int setup_wakeup(uint64_t sleep_val)
+{
+ struct tcs_cmd cmd[3] = { { 0 } };
+
+ cmd[0].data = sleep_val & 0xFFFFFFFF;
+ cmd[1].data = (sleep_val >> 32) & PDC_TIME_UPPER_MASK;
+ cmd[1].data |= 1 << PDC_TIME_VALID_SHIFT;
+
+ return rpmh_write_control(rpmh_client, cmd, ARRAY_SIZE(cmd));
+}
+
+/**
+ * system_sleep_enter() - Activties done when entering system low power modes
+ *
+ * @sleep_val: The qtimer value for the next wakeup time
+ *
+ * Returns 0 for success or error values from writing the timer value in the
+ * hardware block.
+ */
+int system_sleep_enter(uint64_t sleep_val)
+{
+ int ret;
+
+ if (IS_ERR_OR_NULL(rpmh_client))
+ return -EFAULT;
+
+ ret = rpmh_flush(rpmh_client);
+ if (ret)
+ return ret;
+
+ return setup_wakeup(sleep_val);
+}
+EXPORT_SYMBOL(system_sleep_enter);
+
+/**
+ * system_sleep_exit() - Activities done when exiting system low power modes
+ */
+void system_sleep_exit(void)
+{
+}
+EXPORT_SYMBOL(system_sleep_exit);
+
+static int sys_pm_probe(struct platform_device *pdev)
+{
+ rpmh_client = rpmh_get_byindex(pdev, 0);
+ if (IS_ERR_OR_NULL(rpmh_client))
+ return PTR_ERR(rpmh_client);
+
+ return 0;
+}
+
+static const struct of_device_id sys_pm_drv_match[] = {
+ { .compatible = "qcom,system-pm", },
+ { }
+};
+
+static struct platform_driver sys_pm_driver = {
+ .probe = sys_pm_probe,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .of_match_table = sys_pm_drv_match,
+ },
+};
+builtin_platform_driver(sys_pm_driver);
diff --git a/include/soc/qcom/system_pm.h b/include/soc/qcom/system_pm.h
new file mode 100644
index 0000000..0be089b
--- /dev/null
+++ b/include/soc/qcom/system_pm.h
@@ -0,0 +1,28 @@
+/* Copyright (c) 2016, 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 __SOC_QCOM_SYS_PM_H__
+#define __SOC_QCOM_SYS_PM_H__
+
+#ifdef CONFIG_QTI_SYSTEM_PM
+int system_sleep_enter(uint64_t sleep_val);
+
+void system_sleep_exit(void);
+#else
+static inline int system_sleep_enter(uint64_t sleep_val)
+{ return -ENODEV; }
+
+static inline void system_sleep_exit(void)
+{ }
+#endif /* CONFIG_QTI_SYSTEM_PM */
+
+#endif /* __SOC_QCOM_SYS_PM_H__ */