Loading drivers/soc/qcom/icnss.c +31 −18 Original line number Diff line number Diff line Loading @@ -606,6 +606,21 @@ bool icnss_is_fw_ready(void) } EXPORT_SYMBOL(icnss_is_fw_ready); void icnss_block_shutdown(bool status) { if (!penv) return; if (status) { set_bit(ICNSS_BLOCK_SHUTDOWN, &penv->state); reinit_completion(&penv->unblock_shutdown); } else { clear_bit(ICNSS_BLOCK_SHUTDOWN, &penv->state); complete(&penv->unblock_shutdown); } } EXPORT_SYMBOL(icnss_block_shutdown); bool icnss_is_fw_down(void) { if (!penv) Loading Loading @@ -885,8 +900,7 @@ static int icnss_call_driver_probe(struct icnss_priv *priv) icnss_hw_power_on(priv); set_bit(ICNSS_DRIVER_LOADING, &priv->state); reinit_completion(&penv->driver_probed); icnss_block_shutdown(true); while (probe_cnt < ICNSS_MAX_PROBE_CNT) { ret = priv->ops->probe(&priv->pdev->dev); probe_cnt++; Loading @@ -896,13 +910,11 @@ static int icnss_call_driver_probe(struct icnss_priv *priv) if (ret < 0) { icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n", ret, priv->state, probe_cnt); complete(&penv->driver_probed); clear_bit(ICNSS_DRIVER_LOADING, &penv->state); icnss_block_shutdown(false); goto out; } complete(&penv->driver_probed); clear_bit(ICNSS_DRIVER_LOADING, &priv->state); icnss_block_shutdown(false); set_bit(ICNSS_DRIVER_PROBED, &priv->state); return 0; Loading Loading @@ -960,16 +972,20 @@ static int icnss_pd_restart_complete(struct icnss_priv *priv) icnss_hw_power_on(priv); icnss_block_shutdown(true); ret = priv->ops->reinit(&priv->pdev->dev); if (ret < 0) { icnss_fatal_err("Driver reinit failed: %d, state: 0x%lx\n", ret, priv->state); if (!priv->allow_recursive_recovery) ICNSS_ASSERT(false); icnss_block_shutdown(false); goto out_power_off; } out: icnss_block_shutdown(false); clear_bit(ICNSS_SHUTDOWN_DONE, &penv->state); return 0; Loading Loading @@ -1041,8 +1057,7 @@ static int icnss_driver_event_register_driver(void *data) if (ret) goto out; set_bit(ICNSS_DRIVER_LOADING, &penv->state); reinit_completion(&penv->driver_probed); icnss_block_shutdown(true); while (probe_cnt < ICNSS_MAX_PROBE_CNT) { ret = penv->ops->probe(&penv->pdev->dev); probe_cnt++; Loading @@ -1052,13 +1067,11 @@ static int icnss_driver_event_register_driver(void *data) if (ret) { icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n", ret, penv->state, probe_cnt); clear_bit(ICNSS_DRIVER_LOADING, &penv->state); complete(&penv->driver_probed); icnss_block_shutdown(false); goto power_off; } complete(&penv->driver_probed); clear_bit(ICNSS_DRIVER_LOADING, &penv->state); icnss_block_shutdown(false); set_bit(ICNSS_DRIVER_PROBED, &penv->state); return 0; Loading Loading @@ -1284,8 +1297,8 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, return NOTIFY_OK; if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed && test_bit(ICNSS_DRIVER_LOADING, &priv->state)) { if (!wait_for_completion_timeout(&priv->driver_probed, test_bit(ICNSS_BLOCK_SHUTDOWN, &priv->state)) { if (!wait_for_completion_timeout(&priv->unblock_shutdown, PROBE_TIMEOUT)) icnss_pr_err("wlan driver probe timeout\n"); } Loading Loading @@ -2601,8 +2614,8 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv) case ICNSS_MODE_ON: seq_puts(s, "MODE ON DONE"); continue; case ICNSS_DRIVER_LOADING: seq_puts(s, "WLAN DRIVER LOADING"); case ICNSS_BLOCK_SHUTDOWN: seq_puts(s, "BLOCK SHUTDOWN"); } seq_printf(s, "UNKNOWN-%d", i); Loading Loading @@ -3226,7 +3239,7 @@ static int icnss_probe(struct platform_device *pdev) penv = priv; init_completion(&priv->driver_probed); init_completion(&priv->unblock_shutdown); icnss_pr_info("Platform driver probed successfully\n"); Loading @@ -3250,7 +3263,7 @@ static int icnss_remove(struct platform_device *pdev) icnss_debugfs_destroy(penv); complete_all(&penv->driver_probed); complete_all(&penv->unblock_shutdown); icnss_modem_ssr_unregister_notifier(penv); Loading drivers/soc/qcom/icnss_private.h +2 −2 Original line number Diff line number Diff line Loading @@ -156,7 +156,7 @@ enum icnss_driver_state { ICNSS_DRIVER_UNLOADING, ICNSS_REJUVENATE, ICNSS_MODE_ON, ICNSS_DRIVER_LOADING, ICNSS_BLOCK_SHUTDOWN, }; struct ce_irq_list { Loading Loading @@ -355,7 +355,7 @@ struct icnss_priv { bool is_hyp_disabled; uint32_t fw_error_fatal_irq; uint32_t fw_early_crash_irq; struct completion driver_probed; struct completion unblock_shutdown; char function_name[WLFW_FUNCTION_NAME_LEN + 1]; }; Loading include/soc/qcom/icnss.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2019, 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 Loading Loading @@ -144,4 +144,5 @@ extern bool icnss_is_fw_ready(void); extern bool icnss_is_fw_down(void); extern bool icnss_is_rejuvenate(void); extern int icnss_trigger_recovery(struct device *dev); extern void icnss_block_shutdown(bool status); #endif /* _ICNSS_WLAN_H_ */ Loading
drivers/soc/qcom/icnss.c +31 −18 Original line number Diff line number Diff line Loading @@ -606,6 +606,21 @@ bool icnss_is_fw_ready(void) } EXPORT_SYMBOL(icnss_is_fw_ready); void icnss_block_shutdown(bool status) { if (!penv) return; if (status) { set_bit(ICNSS_BLOCK_SHUTDOWN, &penv->state); reinit_completion(&penv->unblock_shutdown); } else { clear_bit(ICNSS_BLOCK_SHUTDOWN, &penv->state); complete(&penv->unblock_shutdown); } } EXPORT_SYMBOL(icnss_block_shutdown); bool icnss_is_fw_down(void) { if (!penv) Loading Loading @@ -885,8 +900,7 @@ static int icnss_call_driver_probe(struct icnss_priv *priv) icnss_hw_power_on(priv); set_bit(ICNSS_DRIVER_LOADING, &priv->state); reinit_completion(&penv->driver_probed); icnss_block_shutdown(true); while (probe_cnt < ICNSS_MAX_PROBE_CNT) { ret = priv->ops->probe(&priv->pdev->dev); probe_cnt++; Loading @@ -896,13 +910,11 @@ static int icnss_call_driver_probe(struct icnss_priv *priv) if (ret < 0) { icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n", ret, priv->state, probe_cnt); complete(&penv->driver_probed); clear_bit(ICNSS_DRIVER_LOADING, &penv->state); icnss_block_shutdown(false); goto out; } complete(&penv->driver_probed); clear_bit(ICNSS_DRIVER_LOADING, &priv->state); icnss_block_shutdown(false); set_bit(ICNSS_DRIVER_PROBED, &priv->state); return 0; Loading Loading @@ -960,16 +972,20 @@ static int icnss_pd_restart_complete(struct icnss_priv *priv) icnss_hw_power_on(priv); icnss_block_shutdown(true); ret = priv->ops->reinit(&priv->pdev->dev); if (ret < 0) { icnss_fatal_err("Driver reinit failed: %d, state: 0x%lx\n", ret, priv->state); if (!priv->allow_recursive_recovery) ICNSS_ASSERT(false); icnss_block_shutdown(false); goto out_power_off; } out: icnss_block_shutdown(false); clear_bit(ICNSS_SHUTDOWN_DONE, &penv->state); return 0; Loading Loading @@ -1041,8 +1057,7 @@ static int icnss_driver_event_register_driver(void *data) if (ret) goto out; set_bit(ICNSS_DRIVER_LOADING, &penv->state); reinit_completion(&penv->driver_probed); icnss_block_shutdown(true); while (probe_cnt < ICNSS_MAX_PROBE_CNT) { ret = penv->ops->probe(&penv->pdev->dev); probe_cnt++; Loading @@ -1052,13 +1067,11 @@ static int icnss_driver_event_register_driver(void *data) if (ret) { icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n", ret, penv->state, probe_cnt); clear_bit(ICNSS_DRIVER_LOADING, &penv->state); complete(&penv->driver_probed); icnss_block_shutdown(false); goto power_off; } complete(&penv->driver_probed); clear_bit(ICNSS_DRIVER_LOADING, &penv->state); icnss_block_shutdown(false); set_bit(ICNSS_DRIVER_PROBED, &penv->state); return 0; Loading Loading @@ -1284,8 +1297,8 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, return NOTIFY_OK; if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed && test_bit(ICNSS_DRIVER_LOADING, &priv->state)) { if (!wait_for_completion_timeout(&priv->driver_probed, test_bit(ICNSS_BLOCK_SHUTDOWN, &priv->state)) { if (!wait_for_completion_timeout(&priv->unblock_shutdown, PROBE_TIMEOUT)) icnss_pr_err("wlan driver probe timeout\n"); } Loading Loading @@ -2601,8 +2614,8 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv) case ICNSS_MODE_ON: seq_puts(s, "MODE ON DONE"); continue; case ICNSS_DRIVER_LOADING: seq_puts(s, "WLAN DRIVER LOADING"); case ICNSS_BLOCK_SHUTDOWN: seq_puts(s, "BLOCK SHUTDOWN"); } seq_printf(s, "UNKNOWN-%d", i); Loading Loading @@ -3226,7 +3239,7 @@ static int icnss_probe(struct platform_device *pdev) penv = priv; init_completion(&priv->driver_probed); init_completion(&priv->unblock_shutdown); icnss_pr_info("Platform driver probed successfully\n"); Loading @@ -3250,7 +3263,7 @@ static int icnss_remove(struct platform_device *pdev) icnss_debugfs_destroy(penv); complete_all(&penv->driver_probed); complete_all(&penv->unblock_shutdown); icnss_modem_ssr_unregister_notifier(penv); Loading
drivers/soc/qcom/icnss_private.h +2 −2 Original line number Diff line number Diff line Loading @@ -156,7 +156,7 @@ enum icnss_driver_state { ICNSS_DRIVER_UNLOADING, ICNSS_REJUVENATE, ICNSS_MODE_ON, ICNSS_DRIVER_LOADING, ICNSS_BLOCK_SHUTDOWN, }; struct ce_irq_list { Loading Loading @@ -355,7 +355,7 @@ struct icnss_priv { bool is_hyp_disabled; uint32_t fw_error_fatal_irq; uint32_t fw_early_crash_irq; struct completion driver_probed; struct completion unblock_shutdown; char function_name[WLFW_FUNCTION_NAME_LEN + 1]; }; Loading
include/soc/qcom/icnss.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2019, 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 Loading Loading @@ -144,4 +144,5 @@ extern bool icnss_is_fw_ready(void); extern bool icnss_is_fw_down(void); extern bool icnss_is_rejuvenate(void); extern int icnss_trigger_recovery(struct device *dev); extern void icnss_block_shutdown(bool status); #endif /* _ICNSS_WLAN_H_ */