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

Commit 12eeab95 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "icnss: Monitor external clock for WLAN"

parents 5b7bd01c f884eeaf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ Optional properties:
  - qcom,smmu-s1-bypass: Boolean context flag to set SMMU to S1 bypass
  - qcom,wlan-msa-fixed-region: phandle, specifier pairs to children of /reserved-memory
  - qcom,hyp_disabled: Boolean context flag to disable hyperviser
  - qcom,clk-monitor-enable: Boolean context flag to enable monitoring external clock

WLAN SMP2P sub nodes

+96 −2
Original line number Diff line number Diff line
@@ -70,6 +70,9 @@
#define ICNSS_QUIRKS_DEFAULT		BIT(FW_REJUVENATE_ENABLE)
#define ICNSS_MAX_PROBE_CNT		2

#define SUBSYS_INTERNAL_MODEM_NAME	"modem"
#define SUBSYS_EXTERNAL_MODEM_NAME	"esoc0"

#define PROBE_TIMEOUT			5000

static struct icnss_priv *penv;
@@ -964,6 +967,13 @@ static int icnss_driver_event_server_arrive(void *data)

	set_bit(ICNSS_WLFW_CONNECTED, &penv->state);

	if (penv->clk_monitor_enable &&
	    !test_bit(ICNSS_CLK_UP, &penv->state)) {
		reinit_completion(&penv->clk_complete);
		icnss_pr_dbg("Waiting for CLK up notification\n");
		wait_for_completion(&penv->clk_complete);
	}

	ret = icnss_hw_power_on(penv);
	if (ret)
		goto clear_server;
@@ -1560,6 +1570,68 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
	return NOTIFY_OK;
}

static int icnss_ext_modem_notifier_nb(struct notifier_block *nb,
				       unsigned long code,
				       void *data)
{
	struct icnss_priv *priv = container_of(nb, struct icnss_priv,
					       ext_modem_ssr_nb);
	icnss_pr_vdbg("EXT-Modem-Notify: event %lu\n", code);


	if (code == SUBSYS_AFTER_POWERUP) {
		set_bit(ICNSS_CLK_UP, &priv->state);
		complete(&priv->clk_complete);
	}

	return NOTIFY_OK;
}

static int icnss_ext_modem_ssr_register_notifier(struct icnss_priv *priv)
{
	int ret = 0;

	priv->ext_modem_ssr_nb.notifier_call = icnss_ext_modem_notifier_nb;

	priv->ext_modem_notify_handler =
		subsys_notif_register_notifier(SUBSYS_EXTERNAL_MODEM_NAME,
					       &priv->ext_modem_ssr_nb);

	if (IS_ERR_OR_NULL(priv->ext_modem_notify_handler)) {
		ret = PTR_ERR(priv->ext_modem_notify_handler);
		icnss_pr_err("External Modem register notifier failed %d\n",
			     ret);
		priv->ext_modem_notify_handler = NULL;
		/* In NULL case */
		if (ret == 0)
			ret = -EINVAL;
		return ret;
	}

	init_completion(&priv->clk_complete);

	return ret;
}

static int icnss_ext_modem_ssr_unregister_notifier(struct icnss_priv *priv)
{
	int ret = 0;

	if (!priv->ext_modem_notify_handler)
		return 0;

	complete_all(&priv->clk_complete);
	ret = subsys_notif_unregister_notifier(priv->ext_modem_notify_handler,
					       &priv->ext_modem_ssr_nb);
	if (ret)
		icnss_pr_err("Fail to unregister external Modem notifier %d\n",
			     ret);

	priv->ext_modem_notify_handler = NULL;

	return 0;
}

static int icnss_modem_ssr_register_notifier(struct icnss_priv *priv)
{
	int ret = 0;
@@ -1567,7 +1639,8 @@ static int icnss_modem_ssr_register_notifier(struct icnss_priv *priv)
	priv->modem_ssr_nb.notifier_call = icnss_modem_notifier_nb;

	priv->modem_notify_handler =
		subsys_notif_register_notifier("modem", &priv->modem_ssr_nb);
		subsys_notif_register_notifier(SUBSYS_INTERNAL_MODEM_NAME,
					       &priv->modem_ssr_nb);

	if (IS_ERR(priv->modem_notify_handler)) {
		ret = PTR_ERR(priv->modem_notify_handler);
@@ -2826,6 +2899,10 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
			continue;
		case ICNSS_PDR:
			seq_puts(s, "PDR TRIGGERED");
			continue;
		case ICNSS_CLK_UP:
			seq_puts(s, "CLK UP");
			continue;
		}

		seq_printf(s, "UNKNOWN-%d", i);
@@ -3492,6 +3569,19 @@ static int icnss_probe(struct platform_device *pdev)
		}
	}

	if (of_property_read_bool(pdev->dev.of_node,
				  "qcom,clk-monitor-enable")) {
		priv->clk_monitor_enable = true;
		icnss_pr_dbg("CLK monitor is enabled\n");
	}

	if (priv->clk_monitor_enable) {
		ret = icnss_ext_modem_ssr_register_notifier(priv);
		if (ret)
			goto out_smmu_deinit;

	}

	spin_lock_init(&priv->event_lock);
	spin_lock_init(&priv->on_off_lock);
	mutex_init(&priv->dev_lock);
@@ -3500,7 +3590,7 @@ static int icnss_probe(struct platform_device *pdev)
	if (!priv->event_wq) {
		icnss_pr_err("Workqueue creation failed\n");
		ret = -EFAULT;
		goto out_smmu_deinit;
		goto out_unregister_ext_modem;
	}

	INIT_WORK(&priv->event_work, icnss_driver_event_work);
@@ -3533,6 +3623,8 @@ static int icnss_probe(struct platform_device *pdev)

out_destroy_wq:
	destroy_workqueue(priv->event_wq);
out_unregister_ext_modem:
	icnss_ext_modem_ssr_unregister_notifier(priv);
out_smmu_deinit:
	icnss_smmu_deinit(priv);
out:
@@ -3563,6 +3655,8 @@ static int icnss_remove(struct platform_device *pdev)
	if (penv->event_wq)
		destroy_workqueue(penv->event_wq);

	icnss_ext_modem_ssr_unregister_notifier(penv);

	icnss_hw_power_off(penv);

	icnss_assign_msa_perm_all(penv, ICNSS_MSA_PERM_HLOS_ALL);
+5 −0
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ enum icnss_driver_state {
	ICNSS_MODE_ON,
	ICNSS_BLOCK_SHUTDOWN,
	ICNSS_PDR,
	ICNSS_CLK_UP,
};

struct ce_irq_list {
@@ -373,6 +374,10 @@ struct icnss_priv {
	struct kobject *icnss_kobject;
	atomic_t is_shutdown;
	bool is_ssr;
	bool clk_monitor_enable;
	void *ext_modem_notify_handler;
	struct notifier_block ext_modem_ssr_nb;
	struct completion clk_complete;
};

int icnss_call_driver_uevent(struct icnss_priv *priv,