Merge "icnss: Add Api to Block/Unblock modem shutdown"

This commit is contained in:
Linux Build Service Account 2019-03-27 08:14:52 -07:00 committed by Gerrit - the friendly Code Review server
commit cbdb77b292
2 changed files with 41 additions and 7 deletions

View file

@ -75,6 +75,8 @@ module_param(qmi_timeout, ulong, 0600);
#define ICNSS_MAX_PROBE_CNT 2
#define PROBE_TIMEOUT 5000
#define icnss_ipc_log_string(_x...) do { \
if (icnss_ipc_log_context) \
ipc_log_string(icnss_ipc_log_context, _x); \
@ -299,6 +301,7 @@ enum icnss_driver_state {
ICNSS_FW_DOWN,
ICNSS_DRIVER_UNLOADING,
ICNSS_REJUVENATE,
ICNSS_BLOCK_SHUTDOWN,
};
struct ce_irq_list {
@ -491,6 +494,7 @@ static struct icnss_priv {
u8 requesting_sub_system;
u16 line_number;
char function_name[QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1];
struct completion unblock_shutdown;
} *penv;
#ifdef CONFIG_ICNSS_DEBUG
@ -1178,6 +1182,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)
@ -2203,6 +2222,7 @@ static int icnss_call_driver_probe(struct icnss_priv *priv)
icnss_hw_power_on(priv);
icnss_block_shutdown(true);
while (probe_cnt < ICNSS_MAX_PROBE_CNT) {
ret = priv->ops->probe(&priv->pdev->dev);
probe_cnt++;
@ -2212,9 +2232,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);
icnss_block_shutdown(false);
goto out;
}
icnss_block_shutdown(false);
set_bit(ICNSS_DRIVER_PROBED, &priv->state);
return 0;
@ -2350,6 +2372,7 @@ static int icnss_driver_event_register_driver(void *data)
if (ret)
goto out;
icnss_block_shutdown(true);
while (probe_cnt < ICNSS_MAX_PROBE_CNT) {
ret = penv->ops->probe(&penv->pdev->dev);
probe_cnt++;
@ -2359,9 +2382,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);
icnss_block_shutdown(false);
goto power_off;
}
icnss_block_shutdown(false);
set_bit(ICNSS_DRIVER_PROBED, &penv->state);
return 0;
@ -2584,6 +2609,13 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
if (code != SUBSYS_BEFORE_SHUTDOWN)
return NOTIFY_OK;
if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed &&
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");
}
if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed) {
ret = wlfw_send_modem_shutdown_msg();
if (ret)
@ -3980,6 +4012,9 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
continue;
case ICNSS_DRIVER_UNLOADING:
seq_puts(s, "DRIVER UNLOADING");
continue;
case ICNSS_BLOCK_SHUTDOWN:
seq_puts(s, "BLOCK SHUTDOWN");
}
seq_printf(s, "UNKNOWN-%d", i);
@ -4651,6 +4686,8 @@ static int icnss_probe(struct platform_device *pdev)
penv = priv;
init_completion(&priv->unblock_shutdown);
icnss_pr_info("Platform driver probed successfully\n");
return 0;
@ -4673,6 +4710,8 @@ static int icnss_remove(struct platform_device *pdev)
icnss_debugfs_destroy(penv);
complete_all(&penv->unblock_shutdown);
icnss_modem_ssr_unregister_notifier(penv);
destroy_ramdump_device(penv->msa0_dump_dev);

View file

@ -1,4 +1,4 @@
/* 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
@ -157,10 +157,5 @@ extern bool icnss_is_rejuvenate(void);
extern int icnss_set_wlan_mac_address(const u8 *in, const uint32_t len);
extern u8 *icnss_get_wlan_mac_address(struct device *dev, uint32_t *num);
extern int icnss_trigger_recovery(struct device *dev);
extern void cnss_set_cc_source(enum cnss_cc_src cc_source);
extern enum cnss_cc_src cnss_get_cc_source(void);
extern int icnss_get_driver_load_cnt(void);
extern void icnss_increment_driver_load_cnt(void);
extern void icnss_set_cc_source(enum cnss_cc_src cc_source);
extern enum cnss_cc_src icnss_get_cc_source(void);
extern void icnss_block_shutdown(bool status);
#endif /* _ICNSS_WLAN_H_ */