Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db6ef570 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "icnss: Defer modem graceful shutdown until probe complete"

parents 18cc53ed fa6cedc6
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -76,6 +76,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);		\
@@ -286,6 +288,7 @@ enum icnss_driver_state {
	ICNSS_DRIVER_UNLOADING,
	ICNSS_REJUVENATE,
	ICNSS_MODE_ON,
	ICNSS_DRIVER_LOADING,
};

struct ce_irq_list {
@@ -475,6 +478,7 @@ static struct icnss_priv {
	struct mutex dev_lock;
	uint32_t fw_error_fatal_irq;
	uint32_t fw_early_crash_irq;
	struct completion driver_probed;
} *penv;

#ifdef CONFIG_ICNSS_DEBUG
@@ -2256,6 +2260,8 @@ 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);
	while (probe_cnt < ICNSS_MAX_PROBE_CNT) {
		ret = priv->ops->probe(&priv->pdev->dev);
		probe_cnt++;
@@ -2265,9 +2271,13 @@ 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);
		goto out;
	}

	complete(&penv->driver_probed);
	clear_bit(ICNSS_DRIVER_LOADING, &penv->state);
	set_bit(ICNSS_DRIVER_PROBED, &priv->state);

	return 0;
@@ -2406,6 +2416,8 @@ 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);
	while (probe_cnt < ICNSS_MAX_PROBE_CNT) {
		ret = penv->ops->probe(&penv->pdev->dev);
		probe_cnt++;
@@ -2415,9 +2427,13 @@ 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);
		goto power_off;
	}

	complete(&penv->driver_probed);
	clear_bit(ICNSS_DRIVER_LOADING, &penv->state);
	set_bit(ICNSS_DRIVER_PROBED, &penv->state);

	return 0;
@@ -2685,6 +2701,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_DRIVER_LOADING, &priv->state)) {
		if (!wait_for_completion_timeout(&priv->driver_probed,
						 PROBE_TIMEOUT))
			icnss_pr_err("wlan driver probe timeout\n");
	}

	if (test_bit(ICNSS_PDR_REGISTERED, &priv->state)) {
		set_bit(ICNSS_FW_DOWN, &priv->state);
		icnss_ignore_qmi_timeout(true);
@@ -4050,6 +4073,9 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
			continue;
		case ICNSS_MODE_ON:
			seq_puts(s, "MODE ON DONE");
			continue;
		case ICNSS_DRIVER_LOADING:
			seq_puts(s, "WLAN DRIVER LOADING");
		}

		seq_printf(s, "UNKNOWN-%d", i);
@@ -4721,6 +4747,8 @@ static int icnss_probe(struct platform_device *pdev)

	penv = priv;

	init_completion(&priv->driver_probed);

	icnss_pr_info("Platform driver probed successfully\n");

	return 0;
@@ -4743,6 +4771,8 @@ static int icnss_remove(struct platform_device *pdev)

	icnss_debugfs_destroy(penv);

	complete_all(&penv->driver_probed);

	icnss_modem_ssr_unregister_notifier(penv);

	destroy_ramdump_device(penv->msa0_dump_dev);