Loading drivers/net/wireless/wcnss/wcnss_wlan.c +74 −5 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include <linux/mfd/pm8xxx/misc.h> #include <linux/qpnp/qpnp-adc.h> #include <linux/pinctrl/consumer.h> #include <linux/pm_qos.h> #include <soc/qcom/subsystem_restart.h> #include <soc/qcom/subsystem_notif.h> Loading @@ -51,6 +52,10 @@ #define WCNSS_PINCTRL_STATE_SLEEP "wcnss_sleep" #define WCNSS_PINCTRL_GPIO_STATE_DEFAULT "wcnss_gpio_default" #define WCNSS_DISABLE_PC_LATENCY 100 #define WCNSS_ENABLE_PC_LATENCY PM_QOS_DEFAULT_VALUE #define WCNSS_PM_QOS_TIMEOUT 15000 /* module params */ #define WCNSS_CONFIG_UNSPECIFIED (-1) #define UINT32_MAX (0xFFFFFFFFU) Loading Loading @@ -409,6 +414,9 @@ static struct { int gpios[WCNSS_WLAN_MAX_GPIO]; int use_pinctrl; u8 is_shutdown; struct pm_qos_request wcnss_pm_qos_request; int pc_disabled; struct delayed_work wcnss_pm_qos_del_req; } *penv = NULL; static ssize_t wcnss_wlan_macaddr_store(struct device *dev, Loading Loading @@ -1115,6 +1123,46 @@ static void wcnss_remove_sysfs(struct device *dev) device_remove_file(dev, &dev_attr_wcnss_mac_addr); } } static void wcnss_pm_qos_add_request(void) { pr_info("%s: add request", __func__); pm_qos_add_request(&penv->wcnss_pm_qos_request, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); } static void wcnss_pm_qos_remove_request(void) { pr_info("%s: remove request", __func__); pm_qos_remove_request(&penv->wcnss_pm_qos_request); } void wcnss_pm_qos_update_request(int val) { pr_info("%s: update request %d", __func__, val); pm_qos_update_request(&penv->wcnss_pm_qos_request, val); } void wcnss_disable_pc_remove_req(void) { if (penv->pc_disabled) { wcnss_pm_qos_update_request(WCNSS_ENABLE_PC_LATENCY); wcnss_pm_qos_remove_request(); wcnss_allow_suspend(); penv->pc_disabled = 0; } } void wcnss_disable_pc_add_req(void) { if (!penv->pc_disabled) { wcnss_pm_qos_add_request(); wcnss_prevent_suspend(); wcnss_pm_qos_update_request(WCNSS_DISABLE_PC_LATENCY); penv->pc_disabled = 1; } } static void wcnss_smd_notify_event(void *data, unsigned int event) { int len = 0; Loading @@ -1138,6 +1186,8 @@ static void wcnss_smd_notify_event(void *data, unsigned int event) WCNSS_CTRL_CHANNEL); schedule_work(&penv->wcnssctrl_version_work); schedule_work(&penv->wcnss_pm_config_work); cancel_delayed_work(&penv->wcnss_pm_qos_del_req); schedule_delayed_work(&penv->wcnss_pm_qos_del_req, 0); break; Loading Loading @@ -2122,6 +2172,11 @@ static void wcnss_send_pm_config(struct work_struct *worker) return; } static void wcnss_pm_qos_enable_pc(struct work_struct *worker) { wcnss_disable_pc_remove_req(); return; } static DECLARE_RWSEM(wcnss_pm_sem); Loading Loading @@ -2552,8 +2607,11 @@ wcnss_trigger_config(struct platform_device *pdev) INIT_WORK(&penv->wcnssctrl_version_work, wcnss_send_version_req); INIT_WORK(&penv->wcnss_pm_config_work, wcnss_send_pm_config); INIT_WORK(&penv->wcnssctrl_nvbin_dnld_work, wcnss_nvbin_dnld_main); INIT_DELAYED_WORK(&penv->wcnss_pm_qos_del_req, wcnss_pm_qos_enable_pc); wake_lock_init(&penv->wcnss_wake_lock, WAKE_LOCK_SUSPEND, "wcnss"); /* Add pm_qos request to disable power collapse for DDR */ wcnss_disable_pc_add_req(); if (wcnss_hardware_type() == WCNSS_PRONTO_HW) { res = platform_get_resource_byname(pdev, Loading Loading @@ -2803,6 +2861,7 @@ wcnss_trigger_config(struct platform_device *pdev) if (IS_ERR(penv->pil)) { dev_err(&pdev->dev, "Peripheral Loader failed on WCNSS.\n"); ret = PTR_ERR(penv->pil); wcnss_disable_pc_add_req(); wcnss_pronto_log_debug_regs(); } } while (pil_retry++ < WCNSS_MAX_PIL_RETRY && IS_ERR(penv->pil)); Loading @@ -2815,6 +2874,8 @@ wcnss_trigger_config(struct platform_device *pdev) penv->pil = NULL; goto fail_ioremap2; } /* Remove pm_qos request */ wcnss_disable_pc_remove_req(); return 0; Loading @@ -2831,6 +2892,7 @@ fail_res: else wcnss_pronto_gpios_config(pdev, false); fail_gpio_res: wcnss_disable_pc_remove_req(); penv = NULL; return ret; } Loading Loading @@ -2962,7 +3024,7 @@ static int wcnss_notif_cb(struct notifier_block *this, unsigned long code, struct notif_data *data = (struct notif_data *)ss_handle; int ret, xo_mode; pr_debug("%s: wcnss notification event: %lu\n", __func__, code); pr_info("%s: wcnss notification event: %lu\n", __func__, code); if (code == SUBSYS_PROXY_VOTE) { if (pdev && pwlanconfig) { Loading @@ -2983,16 +3045,23 @@ static int wcnss_notif_cb(struct notifier_block *this, unsigned long code, WCNSS_WLAN_SWITCH_OFF, NULL); } } else if ((code == SUBSYS_BEFORE_SHUTDOWN && data && data->crashed) || code == SUBSYS_SOC_RESET) code == SUBSYS_SOC_RESET) { wcnss_disable_pc_add_req(); schedule_delayed_work(&penv->wcnss_pm_qos_del_req, msecs_to_jiffies(WCNSS_PM_QOS_TIMEOUT)); wcnss_log_debug_regs_on_bite(); else if (code == SUBSYS_POWERUP_FAILURE) { } else if (code == SUBSYS_POWERUP_FAILURE) { if (pdev && pwlanconfig) wcnss_wlan_power(&pdev->dev, pwlanconfig, WCNSS_WLAN_SWITCH_OFF, NULL); wcnss_pronto_log_debug_regs(); } else if (SUBSYS_BEFORE_SHUTDOWN == code) wcnss_disable_pc_remove_req(); } else if (SUBSYS_BEFORE_SHUTDOWN == code) { wcnss_disable_pc_add_req(); schedule_delayed_work(&penv->wcnss_pm_qos_del_req, msecs_to_jiffies(WCNSS_PM_QOS_TIMEOUT)); penv->is_shutdown = 1; else if (SUBSYS_AFTER_POWERUP == code) } else if (SUBSYS_AFTER_POWERUP == code) penv->is_shutdown = 0; return NOTIFY_DONE; Loading Loading
drivers/net/wireless/wcnss/wcnss_wlan.c +74 −5 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include <linux/mfd/pm8xxx/misc.h> #include <linux/qpnp/qpnp-adc.h> #include <linux/pinctrl/consumer.h> #include <linux/pm_qos.h> #include <soc/qcom/subsystem_restart.h> #include <soc/qcom/subsystem_notif.h> Loading @@ -51,6 +52,10 @@ #define WCNSS_PINCTRL_STATE_SLEEP "wcnss_sleep" #define WCNSS_PINCTRL_GPIO_STATE_DEFAULT "wcnss_gpio_default" #define WCNSS_DISABLE_PC_LATENCY 100 #define WCNSS_ENABLE_PC_LATENCY PM_QOS_DEFAULT_VALUE #define WCNSS_PM_QOS_TIMEOUT 15000 /* module params */ #define WCNSS_CONFIG_UNSPECIFIED (-1) #define UINT32_MAX (0xFFFFFFFFU) Loading Loading @@ -409,6 +414,9 @@ static struct { int gpios[WCNSS_WLAN_MAX_GPIO]; int use_pinctrl; u8 is_shutdown; struct pm_qos_request wcnss_pm_qos_request; int pc_disabled; struct delayed_work wcnss_pm_qos_del_req; } *penv = NULL; static ssize_t wcnss_wlan_macaddr_store(struct device *dev, Loading Loading @@ -1115,6 +1123,46 @@ static void wcnss_remove_sysfs(struct device *dev) device_remove_file(dev, &dev_attr_wcnss_mac_addr); } } static void wcnss_pm_qos_add_request(void) { pr_info("%s: add request", __func__); pm_qos_add_request(&penv->wcnss_pm_qos_request, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); } static void wcnss_pm_qos_remove_request(void) { pr_info("%s: remove request", __func__); pm_qos_remove_request(&penv->wcnss_pm_qos_request); } void wcnss_pm_qos_update_request(int val) { pr_info("%s: update request %d", __func__, val); pm_qos_update_request(&penv->wcnss_pm_qos_request, val); } void wcnss_disable_pc_remove_req(void) { if (penv->pc_disabled) { wcnss_pm_qos_update_request(WCNSS_ENABLE_PC_LATENCY); wcnss_pm_qos_remove_request(); wcnss_allow_suspend(); penv->pc_disabled = 0; } } void wcnss_disable_pc_add_req(void) { if (!penv->pc_disabled) { wcnss_pm_qos_add_request(); wcnss_prevent_suspend(); wcnss_pm_qos_update_request(WCNSS_DISABLE_PC_LATENCY); penv->pc_disabled = 1; } } static void wcnss_smd_notify_event(void *data, unsigned int event) { int len = 0; Loading @@ -1138,6 +1186,8 @@ static void wcnss_smd_notify_event(void *data, unsigned int event) WCNSS_CTRL_CHANNEL); schedule_work(&penv->wcnssctrl_version_work); schedule_work(&penv->wcnss_pm_config_work); cancel_delayed_work(&penv->wcnss_pm_qos_del_req); schedule_delayed_work(&penv->wcnss_pm_qos_del_req, 0); break; Loading Loading @@ -2122,6 +2172,11 @@ static void wcnss_send_pm_config(struct work_struct *worker) return; } static void wcnss_pm_qos_enable_pc(struct work_struct *worker) { wcnss_disable_pc_remove_req(); return; } static DECLARE_RWSEM(wcnss_pm_sem); Loading Loading @@ -2552,8 +2607,11 @@ wcnss_trigger_config(struct platform_device *pdev) INIT_WORK(&penv->wcnssctrl_version_work, wcnss_send_version_req); INIT_WORK(&penv->wcnss_pm_config_work, wcnss_send_pm_config); INIT_WORK(&penv->wcnssctrl_nvbin_dnld_work, wcnss_nvbin_dnld_main); INIT_DELAYED_WORK(&penv->wcnss_pm_qos_del_req, wcnss_pm_qos_enable_pc); wake_lock_init(&penv->wcnss_wake_lock, WAKE_LOCK_SUSPEND, "wcnss"); /* Add pm_qos request to disable power collapse for DDR */ wcnss_disable_pc_add_req(); if (wcnss_hardware_type() == WCNSS_PRONTO_HW) { res = platform_get_resource_byname(pdev, Loading Loading @@ -2803,6 +2861,7 @@ wcnss_trigger_config(struct platform_device *pdev) if (IS_ERR(penv->pil)) { dev_err(&pdev->dev, "Peripheral Loader failed on WCNSS.\n"); ret = PTR_ERR(penv->pil); wcnss_disable_pc_add_req(); wcnss_pronto_log_debug_regs(); } } while (pil_retry++ < WCNSS_MAX_PIL_RETRY && IS_ERR(penv->pil)); Loading @@ -2815,6 +2874,8 @@ wcnss_trigger_config(struct platform_device *pdev) penv->pil = NULL; goto fail_ioremap2; } /* Remove pm_qos request */ wcnss_disable_pc_remove_req(); return 0; Loading @@ -2831,6 +2892,7 @@ fail_res: else wcnss_pronto_gpios_config(pdev, false); fail_gpio_res: wcnss_disable_pc_remove_req(); penv = NULL; return ret; } Loading Loading @@ -2962,7 +3024,7 @@ static int wcnss_notif_cb(struct notifier_block *this, unsigned long code, struct notif_data *data = (struct notif_data *)ss_handle; int ret, xo_mode; pr_debug("%s: wcnss notification event: %lu\n", __func__, code); pr_info("%s: wcnss notification event: %lu\n", __func__, code); if (code == SUBSYS_PROXY_VOTE) { if (pdev && pwlanconfig) { Loading @@ -2983,16 +3045,23 @@ static int wcnss_notif_cb(struct notifier_block *this, unsigned long code, WCNSS_WLAN_SWITCH_OFF, NULL); } } else if ((code == SUBSYS_BEFORE_SHUTDOWN && data && data->crashed) || code == SUBSYS_SOC_RESET) code == SUBSYS_SOC_RESET) { wcnss_disable_pc_add_req(); schedule_delayed_work(&penv->wcnss_pm_qos_del_req, msecs_to_jiffies(WCNSS_PM_QOS_TIMEOUT)); wcnss_log_debug_regs_on_bite(); else if (code == SUBSYS_POWERUP_FAILURE) { } else if (code == SUBSYS_POWERUP_FAILURE) { if (pdev && pwlanconfig) wcnss_wlan_power(&pdev->dev, pwlanconfig, WCNSS_WLAN_SWITCH_OFF, NULL); wcnss_pronto_log_debug_regs(); } else if (SUBSYS_BEFORE_SHUTDOWN == code) wcnss_disable_pc_remove_req(); } else if (SUBSYS_BEFORE_SHUTDOWN == code) { wcnss_disable_pc_add_req(); schedule_delayed_work(&penv->wcnss_pm_qos_del_req, msecs_to_jiffies(WCNSS_PM_QOS_TIMEOUT)); penv->is_shutdown = 1; else if (SUBSYS_AFTER_POWERUP == code) } else if (SUBSYS_AFTER_POWERUP == code) penv->is_shutdown = 0; return NOTIFY_DONE; Loading