Loading Documentation/devicetree/bindings/arm/msm/sleepstate-smp2p.txt 0 → 100644 +13 −0 Original line number Diff line number Diff line Qualcomm Technologies, Inc. SMSM Point-to-Point (SMP2P) Sleepstate driver Required properties: -compatible : should be one of the following: - "qcom,smp2pgpio_sleepstate_3_out" - for sensor processor on remote pid 3 - "qcom,smp2pgpio-sleepstate-out" - for other cases -gpios : the relevant gpio pins of the entry. Example: qcom,smp2pgpio-sleepstate-3-out { compatible = "qcom,smp2pgpio_sleepstate_3_out"; gpios = <&smp2pgpio_sleepstate_3_out 0 0>; }; drivers/soc/qcom/Kconfig +8 −0 Original line number Diff line number Diff line Loading @@ -677,4 +677,12 @@ config QCOM_QHEE_ENABLE_MEM_PROTECTION When this option is enabled, an SCM call will be invoked to enable kernel memory protection in stage 2 memory mappings on kernel boot. This is part of a security feature enabled in QHEE. config QCOM_SMP2P_SLEEPSTATE bool "SMP2P Sleepstate notifier" depends on QCOM_SMP2P help When this option is enabled, notifications are sent to remote procs for the power state changes on the local processor. The notifications are sent through the smp2p framework. endmenu drivers/soc/qcom/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -79,3 +79,4 @@ obj-$(CONFIG_MSM_RPM_SMD) += rpm-smd.o ifdef CONFIG_DEBUG_FS obj-$(CONFIG_MSM_RPM_SMD) += rpm-smd-debug.o endif obj-$(CONFIG_QCOM_SMP2P_SLEEPSTATE) += smp2p_sleepstate.o drivers/soc/qcom/smp2p_sleepstate.c 0 → 100644 +112 −0 Original line number Diff line number Diff line /* Copyright (c) 2014-2018, 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/gpio.h> #include <linux/module.h> #include <linux/of_gpio.h> #include <linux/platform_device.h> #include <linux/suspend.h> #include <linux/delay.h> #include <linux/ipc_router.h> #include "smp2p_private.h" #define SET_DELAY (2 * HZ) #define PROC_AWAKE_ID 12 /* 12th bit */ static int slst_gpio_base_id; /** * sleepstate_pm_notifier() - PM notifier callback function. * @nb: Pointer to the notifier block. * @event: Suspend state event from PM module. * @unused: Null pointer from PM module. * * This function is register as callback function to get notifications * from the PM module on the system suspend state. */ static int sleepstate_pm_notifier(struct notifier_block *nb, unsigned long event, void *unused) { switch (event) { case PM_SUSPEND_PREPARE: gpio_set_value(slst_gpio_base_id + PROC_AWAKE_ID, 0); usleep_range(10000, 10500); /* Tuned based on SMP2P latencies */ msm_ipc_router_set_ws_allowed(true); break; case PM_POST_SUSPEND: gpio_set_value(slst_gpio_base_id + PROC_AWAKE_ID, 1); msm_ipc_router_set_ws_allowed(false); break; } return NOTIFY_DONE; } static struct notifier_block sleepstate_pm_nb = { .notifier_call = sleepstate_pm_notifier, .priority = INT_MAX, }; static int smp2p_sleepstate_probe(struct platform_device *pdev) { int ret; struct device_node *node = pdev->dev.of_node; slst_gpio_base_id = of_get_gpio(node, 0); if (slst_gpio_base_id == -EPROBE_DEFER) { return slst_gpio_base_id; } else if (slst_gpio_base_id < 0) { SMP2P_ERR("%s: Error to get gpio %d\n", __func__, slst_gpio_base_id); return slst_gpio_base_id; } gpio_set_value(slst_gpio_base_id + PROC_AWAKE_ID, 1); ret = register_pm_notifier(&sleepstate_pm_nb); if (ret) SMP2P_ERR("%s: power state notif error %d\n", __func__, ret); return 0; } static const struct of_device_id msm_smp2p_slst_match_table[] = { {.compatible = "qcom,smp2pgpio_sleepstate_3_out"}, {.compatible = "qcom,smp2pgpio-sleepstate-out"}, {}, }; static struct platform_driver smp2p_sleepstate_driver = { .probe = smp2p_sleepstate_probe, .driver = { .name = "smp2p_sleepstate", .owner = THIS_MODULE, .of_match_table = msm_smp2p_slst_match_table, }, }; static int __init smp2p_sleepstate_init(void) { int ret; ret = platform_driver_register(&smp2p_sleepstate_driver); if (ret) { SMP2P_ERR("%s: smp2p_sleepstate_driver register failed %d\n", __func__, ret); return ret; } return 0; } module_init(smp2p_sleepstate_init); MODULE_DESCRIPTION("SMP2P SLEEP STATE"); MODULE_LICENSE("GPL v2"); Loading
Documentation/devicetree/bindings/arm/msm/sleepstate-smp2p.txt 0 → 100644 +13 −0 Original line number Diff line number Diff line Qualcomm Technologies, Inc. SMSM Point-to-Point (SMP2P) Sleepstate driver Required properties: -compatible : should be one of the following: - "qcom,smp2pgpio_sleepstate_3_out" - for sensor processor on remote pid 3 - "qcom,smp2pgpio-sleepstate-out" - for other cases -gpios : the relevant gpio pins of the entry. Example: qcom,smp2pgpio-sleepstate-3-out { compatible = "qcom,smp2pgpio_sleepstate_3_out"; gpios = <&smp2pgpio_sleepstate_3_out 0 0>; };
drivers/soc/qcom/Kconfig +8 −0 Original line number Diff line number Diff line Loading @@ -677,4 +677,12 @@ config QCOM_QHEE_ENABLE_MEM_PROTECTION When this option is enabled, an SCM call will be invoked to enable kernel memory protection in stage 2 memory mappings on kernel boot. This is part of a security feature enabled in QHEE. config QCOM_SMP2P_SLEEPSTATE bool "SMP2P Sleepstate notifier" depends on QCOM_SMP2P help When this option is enabled, notifications are sent to remote procs for the power state changes on the local processor. The notifications are sent through the smp2p framework. endmenu
drivers/soc/qcom/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -79,3 +79,4 @@ obj-$(CONFIG_MSM_RPM_SMD) += rpm-smd.o ifdef CONFIG_DEBUG_FS obj-$(CONFIG_MSM_RPM_SMD) += rpm-smd-debug.o endif obj-$(CONFIG_QCOM_SMP2P_SLEEPSTATE) += smp2p_sleepstate.o
drivers/soc/qcom/smp2p_sleepstate.c 0 → 100644 +112 −0 Original line number Diff line number Diff line /* Copyright (c) 2014-2018, 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/gpio.h> #include <linux/module.h> #include <linux/of_gpio.h> #include <linux/platform_device.h> #include <linux/suspend.h> #include <linux/delay.h> #include <linux/ipc_router.h> #include "smp2p_private.h" #define SET_DELAY (2 * HZ) #define PROC_AWAKE_ID 12 /* 12th bit */ static int slst_gpio_base_id; /** * sleepstate_pm_notifier() - PM notifier callback function. * @nb: Pointer to the notifier block. * @event: Suspend state event from PM module. * @unused: Null pointer from PM module. * * This function is register as callback function to get notifications * from the PM module on the system suspend state. */ static int sleepstate_pm_notifier(struct notifier_block *nb, unsigned long event, void *unused) { switch (event) { case PM_SUSPEND_PREPARE: gpio_set_value(slst_gpio_base_id + PROC_AWAKE_ID, 0); usleep_range(10000, 10500); /* Tuned based on SMP2P latencies */ msm_ipc_router_set_ws_allowed(true); break; case PM_POST_SUSPEND: gpio_set_value(slst_gpio_base_id + PROC_AWAKE_ID, 1); msm_ipc_router_set_ws_allowed(false); break; } return NOTIFY_DONE; } static struct notifier_block sleepstate_pm_nb = { .notifier_call = sleepstate_pm_notifier, .priority = INT_MAX, }; static int smp2p_sleepstate_probe(struct platform_device *pdev) { int ret; struct device_node *node = pdev->dev.of_node; slst_gpio_base_id = of_get_gpio(node, 0); if (slst_gpio_base_id == -EPROBE_DEFER) { return slst_gpio_base_id; } else if (slst_gpio_base_id < 0) { SMP2P_ERR("%s: Error to get gpio %d\n", __func__, slst_gpio_base_id); return slst_gpio_base_id; } gpio_set_value(slst_gpio_base_id + PROC_AWAKE_ID, 1); ret = register_pm_notifier(&sleepstate_pm_nb); if (ret) SMP2P_ERR("%s: power state notif error %d\n", __func__, ret); return 0; } static const struct of_device_id msm_smp2p_slst_match_table[] = { {.compatible = "qcom,smp2pgpio_sleepstate_3_out"}, {.compatible = "qcom,smp2pgpio-sleepstate-out"}, {}, }; static struct platform_driver smp2p_sleepstate_driver = { .probe = smp2p_sleepstate_probe, .driver = { .name = "smp2p_sleepstate", .owner = THIS_MODULE, .of_match_table = msm_smp2p_slst_match_table, }, }; static int __init smp2p_sleepstate_init(void) { int ret; ret = platform_driver_register(&smp2p_sleepstate_driver); if (ret) { SMP2P_ERR("%s: smp2p_sleepstate_driver register failed %d\n", __func__, ret); return ret; } return 0; } module_init(smp2p_sleepstate_init); MODULE_DESCRIPTION("SMP2P SLEEP STATE"); MODULE_LICENSE("GPL v2");