diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index 63011bf09517..160d736ddcf7 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -341,13 +341,3 @@ config POWER_MLXBF This driver supports reset or low power mode handling for Mellanox BlueField. endif - -config PM_SILENT_MODE - tristate "Silent Mode PM operations" - default n - help - This feature is enabled when silent mode is needed in the system. - PM sysfs nodes under: - /sys/kernel/silent_boot/pm_silentmode_kernel_state is used to - indicate the state of the commandline value parsed and - set as part of startup. diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index 4602b162660c..8c30dafcd931 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile @@ -38,5 +38,4 @@ obj-$(CONFIG_REBOOT_MODE) += reboot-mode.o obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o obj-$(CONFIG_POWER_RESET_SC27XX) += sc27xx-poweroff.o obj-$(CONFIG_NVMEM_REBOOT_MODE) += nvmem-reboot-mode.o -obj-$(CONFIG_PM_SILENT_MODE) += silent_boot.o obj-$(CONFIG_POWER_MLXBF) += pwr-mlxbf.o diff --git a/drivers/power/reset/silent_boot.c b/drivers/power/reset/silent_boot.c deleted file mode 100644 index b2fa50e1aff6..000000000000 --- a/drivers/power/reset/silent_boot.c +++ /dev/null @@ -1,277 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static BLOCKING_NOTIFIER_HEAD(pm_silentmode_chain); - -static atomic_t pm_silentmode_userspace_cntrl = - ATOMIC_INIT(USERSPACE_CONTROL_DISABLED); - -/* silent mode is dependent on BootArgs + HW state*/ -static atomic_t pm_silent_mode_enable = - ATOMIC_INIT(MODE_NON_SILENT); - -static atomic_t pm_silentmode_hw_state = - ATOMIC_INIT(MODE_GPIO_LOW); - -static struct kobject *silent_boot_kobj; - -/* - * On the kernel command line specify silent_boot.mode= - * to set mode in silent mode module. - */ -static char *mode = "nonsilent"; -static int silent_mode; -static int silent_mode_param_set(const char *, const struct kernel_param *); -static int silent_mode_param_get(char *, const struct kernel_param *); -static const struct kernel_param_ops silent_mode_param_ops = { - .set = silent_mode_param_set, - .get = silent_mode_param_get, -}; -module_param_cb(mode, &silent_mode_param_ops, &mode, 0644); - -static int silent_mode_param_set(const char *val, const struct kernel_param *kp) -{ - if (!silent_mode) { - int len = strlen("forcednonsilent"); - char *s = strstrip((char *)val); - - if (strnstr(s, "forcednonsilent", len)) { - silent_mode = -MODE_NON_SILENT; - } else if (strnstr(s, "forcedsilent", len)) { - silent_mode = -MODE_SILENT; - } else if (strnstr(s, "nonsilent", len)) { - silent_mode = MODE_NON_SILENT; - } else if (strnstr(s, "silent", len)) { - silent_mode = MODE_SILENT; - } else { - silent_mode = MODE_NON_SILENT; - pr_debug("silent_mode: No string found: NON_SILENT\n"); - } - } - - pr_debug("Silent Mode set to %d\n", silent_mode); - return 0; -} - -static int silent_mode_param_get(char *buf, const struct kernel_param *kp) -{ - return scnprintf(buf, strlen(mode)+1, "%s\n", mode); -} - -/* - * pm_silentmode_kernel_set: Check if userspace is controlling this node - * else go ahead and update the node. - */ -static int pm_silentmode_kernel_set(int val) -{ - if (!atomic_read(&pm_silentmode_userspace_cntrl)) { - pr_debug("%s: Kernel Control sysfs\n", __func__); - atomic_set(&pm_silent_mode_enable, val); - return 0; - } - pr_debug("%s: Userspace Controls sysfs\n", __func__); - return -USERSPACE_CONTROL_ENABLED; -} - -static int pm_silentmode_kernel_get(void) -{ - return atomic_read(&pm_silent_mode_enable); -} - -static void pm_silentmode_hw_state_set(int val) -{ - atomic_set(&pm_silentmode_hw_state, val); -} - -int pm_silentmode_hw_state_get(void) -{ - return atomic_read(&pm_silentmode_hw_state); -} -EXPORT_SYMBOL(pm_silentmode_hw_state_get); - -/* - * External Function to be called by drivers interested in checking - * silent boot mode value and registering a callback if in silent mode - * else return pm_silent_mode_enable value - */ -int register_pm_silentmode_notifier(struct notifier_block *nb) -{ - int lsilent = pm_silentmode_kernel_get(); - - if (lsilent == MODE_SILENT) { - blocking_notifier_chain_register(&pm_silentmode_chain, nb); - pr_debug("%s: ....Registered\n", __func__); - } - return lsilent; -} -EXPORT_SYMBOL(register_pm_silentmode_notifier); - -/* - * External function used for unregistering the callback to the silent mode - * driver for notification - */ -int unregister_pm_silentmode_notifier(struct notifier_block *nb) -{ - return blocking_notifier_chain_unregister - (&pm_silentmode_chain, nb); -} -EXPORT_SYMBOL(unregister_pm_silentmode_notifier); - -static void pm_silent_mode_cb_chain(void) -{ - pr_debug("%s: SilentMode notify\n", __func__); - blocking_notifier_call_chain(&pm_silentmode_chain, 1, NULL); -} - -void pm_silentmode_user_update(struct kobject *kobj, int val) -{ - if (kobj != NULL) { - atomic_set(&pm_silentmode_userspace_cntrl, - USERSPACE_CONTROL_ENABLED); - atomic_set(&pm_silent_mode_enable, val); - sysfs_notify(kobj, NULL, "pm_silentmode_kernel_state"); - } -} - -int pm_silentmode_update(int val, struct kobject *kobj, bool us) -{ - if (us) { - pm_silentmode_user_update(kobj, val); - return 0; - } - - pr_debug("%s:Driver update to sysfs\n", __func__); - pm_silentmode_kernel_set(val ^ 1); - pm_silentmode_hw_state_set((val ^ 1)); - sysfs_notify(silent_boot_kobj, NULL, "pm_silentmode_kernel_state"); - sysfs_notify(silent_boot_kobj, NULL, "pm_silentmode_hw_state"); - pm_silent_mode_cb_chain(); - - return 0; -} -EXPORT_SYMBOL(pm_silentmode_update); - -int pm_silentmode_status(void) -{ - return pm_silentmode_kernel_get(); -} -EXPORT_SYMBOL(pm_silentmode_status); - -int pm_silentmode_get_mode(void) -{ - return silent_mode; -} -EXPORT_SYMBOL(pm_silentmode_get_mode); - -#define silentmode_attr(_name) \ -static struct kobj_attribute _name##_attr = { \ - .attr = { \ - .name = __stringify(_name), \ - .mode = 0664, \ - }, \ - .show = _name##_show, \ - .store = _name##_store, \ -} - -static ssize_t pm_silentmode_kernel_state_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - return scnprintf(buf, PAGE_SIZE, "%d\n", pm_silentmode_status()); -} - -static ssize_t pm_silentmode_kernel_state_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t n) -{ - unsigned long val; - - if (kstrtoul(buf, 10, &val)) - return -EINVAL; - - pm_silentmode_update(val, kobj, 1); - - return n; -} - -silentmode_attr(pm_silentmode_kernel_state); - -static ssize_t pm_silentmode_hw_state_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - return scnprintf(buf, PAGE_SIZE, "%d\n", - pm_silentmode_hw_state_get()); -} - -static ssize_t pm_silentmode_hw_state_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t n) -{ - return -EINVAL; -} -silentmode_attr(pm_silentmode_hw_state); - -static struct attribute *g[] = { - &pm_silentmode_kernel_state_attr.attr, - &pm_silentmode_hw_state_attr.attr, - NULL, -}; - - -static const struct attribute_group attr_group = { - .attrs = g, -}; - -static int __init pm_silentmode_init(void) -{ - int error; - - pr_debug("%s: Silent Boot Mode Entered\n", __func__); - /* 1. Set based on Parse Command Line arguments */ - if (!silent_mode) - silent_mode = MODE_NON_SILENT; - - if (silent_mode == MODE_SILENT || silent_mode == -MODE_SILENT) { - pm_silentmode_hw_state_set(MODE_GPIO_HIGH); - pm_silentmode_kernel_set(1); - } else { - pm_silentmode_hw_state_set(MODE_GPIO_LOW); - pm_silentmode_kernel_set(0); - pr_debug("%s: Silent Boot Mode disabled\n", __func__); - } - - silent_boot_kobj = kobject_create_and_add("silent_boot", kernel_kobj); - if (!silent_boot_kobj) { - pr_err("%s: Failed to add silent_boot_kobj\n", __func__); - return -ENOMEM; - } - - /* 2. Append sysfs entries under /sys/kernel/ */ - error = sysfs_create_group(silent_boot_kobj, &attr_group); - if (error) { - pr_err("%s: failed to create sysfs %d\n", __func__, error); - return error; - } - - return 0; -} -postcore_initcall(pm_silentmode_init); - -MODULE_DESCRIPTION("Qualcomm Technologies, Inc. PM Silent Mode driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 330040db33ac..39c8ed4cbe6e 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -97,7 +97,6 @@ wcd_usbss_i2c-y += wcd939x-i2c.o obj-$(CONFIG_QCOM_ADSP_SLEEPMON) += adsp_sleepmon.o obj-$(CONFIG_QCOM_PANEL_EVENT_NOTIFIER) += panel_event_notifier.o obj-$(CONFIG_QCOM_DEBUG_SYMBOL) += debug_symbol.o -obj-$(CONFIG_SILENT_MODE) += silent-mode-hw-monitoring.o obj-$(CONFIG_QCOM_VM_DMESG_DUMPER) += dmesg_dumper.o obj-$(CONFIG_QCOM_VM_ALIVE_LOG_ENCRYPT) += dmesg_dumper_crypto.o obj-$(CONFIG_RENAME_DEVICES) += rename_devices.o diff --git a/drivers/soc/qcom/silent-mode-hw-monitoring.c b/drivers/soc/qcom/silent-mode-hw-monitoring.c deleted file mode 100644 index 3c7a4efc5994..000000000000 --- a/drivers/soc/qcom/silent-mode-hw-monitoring.c +++ /dev/null @@ -1,264 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - - -/** - * struct silent_mode_data : silent mode context data - * @gpio_number: GPIO Instance for silent mode monitoring - * @irq_number: IRQ Number assigned dynamically for silent mode - * @pdev: platform device from device/driver call - * @pm_nb: power manager notification block - * - * Silent mode context data holding all the information needed - * by the driver for device/driver interactions - */ -struct silent_mode_info { - int sgpio; - int sirq; - bool active_low; - struct platform_device *pdev; - struct gpio_desc *gpiod; - struct notifier_block pm_nb; - struct delayed_work work; -}; - -static irqreturn_t silent_mode_irq(int irq, void *priv) -{ - struct silent_mode_info *info = priv; - - mod_delayed_work(system_wq, &info->work, msecs_to_jiffies(200)); - - return IRQ_HANDLED; -} - -static void silent_mode_handler_work_func(struct work_struct *work) -{ - int irq_trig; - struct silent_mode_info *info = - container_of(work, struct silent_mode_info, work.work); - - irq_trig = gpiod_get_value(info->gpiod); - dev_info(&info->pdev->dev, "Irq_trig %d\n", irq_trig); - pm_silentmode_update(irq_trig, NULL, 0); -} - -/** - * silent_mode_init_monitor() - Initialize the Silent Mode monitoring function - * @info: pointer to silent_mode_info structure - * - * This function returns 0 if it succeeds. If an error occurs an - * negative number is returned. - * - * This function will: - * - Request GPIO - * - Set the GPIO direction as input - * - Request a dual-edge GPIO interrupt - * - * Return: - * - 0: if Init passes - * - ERRNO: if Init fails - */ - -static int silent_mode_init_monitor(struct silent_mode_info *info) -{ - int result = -EINVAL; - - dev_info(&info->pdev->dev, "GPIO for Silent boot: %d\n", - info->sgpio); - - if (!gpio_is_valid(info->sgpio)) { - dev_info(&info->pdev->dev, "Invalid gpio Request %d\n", - info->sgpio); - return result; - } - - info->gpiod = gpio_to_desc(info->sgpio); - info->active_low = gpiod_is_active_low(info->gpiod); - info->sirq = gpiod_to_irq(info->gpiod); - result = gpiod_set_debounce(info->gpiod, 15000); - if (result < 0) { - dev_err(&info->pdev->dev, "%s: GPIO debounce ret %d\n", - __func__, result); - return result; - } - - INIT_DELAYED_WORK(&info->work, silent_mode_handler_work_func); - - result = devm_request_any_context_irq(&info->pdev->dev, - info->sirq, - silent_mode_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - "silent_boot_GPIO_handler", - info); - - if (result < 0) - dev_err(&info->pdev->dev, "IRQ request %d\n", result); - - return result; - -} - -static int silent_mode_enable_monitor(struct silent_mode_info *info) -{ - int result = 0; - - dev_info(&info->pdev->dev, "silent_mode:%s\n", __func__); - if (info != NULL) { - result = gpio_get_value(info->sgpio); - if (result != 0) - enable_irq(info->sirq); - else - return -EEXIST; - } - return 0; -} - -static int silent_mode_disable_monitor(struct silent_mode_info *info) -{ - dev_info(&info->pdev->dev, "silent_mode:%s\n", __func__); - if (info != NULL) - disable_irq(info->sirq); - - return 0; -} - -static int forced_mode_enforced(void) -{ - if (pm_silentmode_get_mode() < 0) - return 1; - - return 0; -} - - -static int silent_mode_probe(struct platform_device *pdev) -{ - int result = 0; - unsigned int flags = GPIOF_IN; - struct silent_mode_info *info; - - if (forced_mode_enforced()) { - dev_info(&pdev->dev, "forced_mode: No HW State monitoring\n"); - return result; - } - - dev_info(&pdev->dev, "MODE_SILENT/MODE_NON_SILENT\n"); - - info = devm_kzalloc(&pdev->dev, - sizeof(struct silent_mode_info), - GFP_KERNEL); - if (!info) { - dev_info(&pdev->dev, "%s: FAILED: cannot alloc info data\n", - __func__); - result = -ENOMEM; - return result; - } - - info->pdev = pdev; - platform_set_drvdata(pdev, info); - - info->sgpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,silent-boot-gpio", - 0); - - result = devm_gpio_request_one(&pdev->dev, - info->sgpio, - flags, - "qti-silent-mode"); - if (result < 0) { - dev_err(&pdev->dev, "Failed to request GPIO %d, error %d\n", - info->sgpio, result); - result = -EINVAL; - } - - result = silent_mode_init_monitor(info); - if (result < 0) { - dev_err(&pdev->dev, "Failed Init: %d\n", result); - result = -EINVAL; - } - - return result; -} - -#ifdef CONFIG_PM -static int silent_mode_suspend_late(struct device *dev) -{ - int ret = 0; - struct platform_device *pdev = to_platform_device(dev); - struct silent_mode_info *info = platform_get_drvdata(pdev); - - ret = silent_mode_disable_monitor(info); - dev_info(&info->pdev->dev, "silent_mode:%s\n", __func__); - return ret; -} - -static int silent_mode_resume_early(struct device *dev) -{ - int ret = 0; - struct platform_device *pdev = to_platform_device(dev); - struct silent_mode_info *info = platform_get_drvdata(pdev); - - ret = silent_mode_enable_monitor(info); - dev_info(&info->pdev->dev, "silent_mode:%s\n", __func__); - return ret; -} - -static const struct dev_pm_ops silent_mode_pm_ops = { - .suspend_late = silent_mode_suspend_late, - .resume_early = silent_mode_resume_early, -}; -#endif - -static int silent_mode_remove(struct platform_device *pdev) -{ - dev_dbg(&pdev->dev, "silent_mode: Entered %s\n", __func__); - return 0; -} - -static const struct of_device_id silent_mode_match_table[] = { - {.compatible = "qcom,silent-mode" }, - { } -}; - -static struct platform_driver silent_mode_driver = { - .probe = silent_mode_probe, - .remove = silent_mode_remove, - .driver = { - .name = "qcom-silent-monitoring-mode", - .of_match_table = silent_mode_match_table, -#ifdef CONFIG_PM - .pm = &silent_mode_pm_ops, -#endif - }, -}; - -module_platform_driver(silent_mode_driver); - -MODULE_DESCRIPTION("Silent Mode Monitoring Driver"); -MODULE_LICENSE("GPL");