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

Commit ffb92f5b authored by Yuanyuan Liu's avatar Yuanyuan Liu Committed by Kyle Yan
Browse files

icnss: Export APIs for power on/off WLAN hardware



Export APIs to WLAN driver to power on/off WLAN hardware.

CRs-Fixed: 1017496
Change-Id: I4b09b7e9ee97129f952d737a530fc04205259f24
Signed-off-by: default avatarYuanyuan Liu <yuanliu@codeaurora.org>
parent a1807a05
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ struct icnss_driver_event {

enum cnss_driver_state {
	ICNSS_WLFW_QMI_CONNECTED,
	ICNSS_POWER_ON,
	ICNSS_FW_READY,
	ICNSS_DRIVER_PROBED,
	ICNSS_FW_TEST_MODE,
@@ -171,6 +172,7 @@ static struct icnss_data {
		icnss_mem_region[QMI_WLFW_MAX_NUM_MEMORY_REGIONS_V01];
	bool skip_qmi;
	struct dentry *root_dentry;
	spinlock_t on_off_lock;
} *penv;

static char *icnss_driver_event_to_str(enum icnss_driver_event_type type)
@@ -391,33 +393,85 @@ static void icnss_hw_reset(struct icnss_data *pdata)
static int icnss_hw_power_on(struct icnss_data *pdata)
{
	int ret = 0;
	unsigned long flags;

	icnss_pr_dbg("Power on: state: 0x%lx\n", pdata->state);

	spin_lock_irqsave(&pdata->on_off_lock, flags);
	if (test_bit(ICNSS_POWER_ON, &pdata->state)) {
		spin_unlock_irqrestore(&pdata->on_off_lock, flags);
		return ret;
	}
	set_bit(ICNSS_POWER_ON, &pdata->state);
	spin_unlock_irqrestore(&pdata->on_off_lock, flags);

	ret = icnss_vreg_set(VREG_ON);
	if (ret)
		goto out;

	icnss_hw_release_reset(pdata);

	return ret;
out:
	clear_bit(ICNSS_POWER_ON, &pdata->state);
	return ret;
}

static int icnss_hw_power_off(struct icnss_data *pdata)
{
	int ret = 0;
	unsigned long flags;

	icnss_pr_dbg("Power off: 0x%lx\n", pdata->state);

	spin_lock_irqsave(&pdata->on_off_lock, flags);
	if (!test_bit(ICNSS_POWER_ON, &pdata->state)) {
		spin_unlock_irqrestore(&pdata->on_off_lock, flags);
		return ret;
	}
	clear_bit(ICNSS_POWER_ON, &pdata->state);
	spin_unlock_irqrestore(&pdata->on_off_lock, flags);

	icnss_hw_reset(pdata);

	ret = icnss_vreg_set(VREG_OFF);
	if (ret)
		goto out;

	return ret;
out:
	set_bit(ICNSS_POWER_ON, &pdata->state);
	return ret;
}

int icnss_power_on(struct device *dev)
{
	struct icnss_data *priv = dev_get_drvdata(dev);

	if (!priv) {
		icnss_pr_err("Invalid drvdata: dev %p, data %p\n",
			     dev, priv);
		return -EINVAL;
	}

	return icnss_hw_power_on(priv);
}
EXPORT_SYMBOL(icnss_power_on);

int icnss_power_off(struct device *dev)
{
	struct icnss_data *priv = dev_get_drvdata(dev);

	if (!priv) {
		icnss_pr_err("Invalid drvdata: dev %p, data %p\n",
			     dev, priv);
		return -EINVAL;
	}

	return icnss_hw_power_off(priv);
}
EXPORT_SYMBOL(icnss_power_off);

static int wlfw_msa_mem_info_send_sync_msg(void)
{
	int ret = 0;
@@ -1813,6 +1867,8 @@ static int icnss_probe(struct platform_device *pdev)
	if (!penv)
		return -ENOMEM;

	dev_set_drvdata(dev, penv);

	penv->pdev = pdev;

	ret = icnss_dt_parse_vreg_info(dev, &penv->vreg_info, "vdd-io");
@@ -1918,6 +1974,7 @@ static int icnss_probe(struct platform_device *pdev)
					       "qcom,skip-qmi");

	spin_lock_init(&penv->event_lock);
	spin_lock_init(&penv->on_off_lock);

	penv->event_wq = alloc_workqueue("icnss_driver_event", 0, 0);
	if (!penv->event_wq) {
@@ -1964,6 +2021,7 @@ unmap_mem_base:
release_regulator:
	icnss_release_resources();
out:
	dev_set_drvdata(dev, NULL);
	devm_kfree(&pdev->dev, penv);
	penv = NULL;
	return ret;
@@ -2000,6 +2058,8 @@ static int icnss_remove(struct platform_device *pdev)

	icnss_release_resources();

	dev_set_drvdata(&pdev->dev, NULL);

	return 0;
}

+2 −0
Original line number Diff line number Diff line
@@ -98,5 +98,7 @@ extern int icnss_ce_request_irq(unsigned int ce_id,
extern int icnss_get_ce_id(int irq);
extern int icnss_set_fw_debug_mode(bool enable_fw_log);
extern int icnss_get_irq(int ce_id);
extern int icnss_power_on(struct device *dev);
extern int icnss_power_off(struct device *dev);

#endif /* _ICNSS_WLAN_H_ */