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

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

Merge "cnss2: Refactor suspend/resume routine code"

parents 5704da2d e825ee0c
Loading
Loading
Loading
Loading
+138 −135
Original line number Diff line number Diff line
@@ -1730,47 +1730,53 @@ static void cnss_dereg_pci_event(struct cnss_pci_data *pci_priv)
	msm_pcie_deregister_event(&pci_priv->msm_pci_event);
}

static int cnss_pci_suspend(struct device *dev)
static int cnss_pci_suspend_driver(struct cnss_pci_data *pci_priv)
{
	struct pci_dev *pci_dev = pci_priv->pci_dev;
	struct cnss_wlan_driver *driver_ops = pci_priv->driver_ops;
	int ret = 0;
	struct pci_dev *pci_dev = to_pci_dev(dev);
	struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
	struct cnss_plat_data *plat_priv;
	struct cnss_wlan_driver *driver_ops;

	pm_message_t state = { .event = PM_EVENT_SUSPEND };

	if (!pci_priv)
		goto out;

	plat_priv = pci_priv->plat_priv;
	if (!plat_priv)
		goto out;

	if (!cnss_is_device_powered_on(plat_priv))
		goto out;

	set_bit(CNSS_IN_SUSPEND_RESUME, &plat_priv->driver_state);

	if (!test_bit(DISABLE_DRV, &plat_priv->ctrl_params.quirks))
		pci_priv->drv_connected_last =
			cnss_pci_get_drv_connected(pci_priv);

	driver_ops = pci_priv->driver_ops;
	if (driver_ops && driver_ops->suspend) {
		ret = driver_ops->suspend(pci_dev, state);
		if (ret) {
			cnss_pr_err("Failed to suspend host driver, err = %d\n",
				    ret);
			ret = -EAGAIN;
			goto clear_flag;
		}
	}

	if (pci_priv->pci_link_state == PCI_LINK_UP && !pci_priv->disable_pc) {
	return ret;
}

static int cnss_pci_resume_driver(struct cnss_pci_data *pci_priv)
{
	struct pci_dev *pci_dev = pci_priv->pci_dev;
	struct cnss_wlan_driver *driver_ops = pci_priv->driver_ops;
	int ret = 0;

	if (driver_ops && driver_ops->resume) {
		ret = driver_ops->resume(pci_dev);
		if (ret)
			cnss_pr_err("Failed to resume host driver, err = %d\n",
				    ret);
	}

	return ret;
}

static int cnss_pci_suspend_bus(struct cnss_pci_data *pci_priv)
{
	struct pci_dev *pci_dev = pci_priv->pci_dev;
	int ret = 0;

	if (pci_priv->pci_link_state == PCI_LINK_DOWN)
		goto out;

	if (cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_SUSPEND)) {
		ret = -EAGAIN;
			goto resume_driver;
		goto out;
	}

	if (pci_priv->drv_connected_last)
@@ -1790,67 +1796,45 @@ static int cnss_pci_suspend(struct device *dev)
		goto resume_mhi;
	}
	pci_priv->pci_link_state = PCI_LINK_DOWN;
	}

	cnss_pci_set_monitor_wake_intr(pci_priv, false);

	return 0;

resume_mhi:
	if (!pci_is_enabled(pci_dev))
		if (pci_enable_device(pci_dev))
			cnss_pr_err("Failed to enable PCI device\n");
	if (pci_priv->saved_state)
		cnss_set_pci_config_space(pci_priv, RESTORE_PCI_CONFIG_SPACE);
	pci_set_master(pci_dev);
	cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RESUME);
resume_driver:
	if (driver_ops && driver_ops->resume)
		driver_ops->resume(pci_dev);
clear_flag:
	pci_priv->drv_connected_last = 0;
	clear_bit(CNSS_IN_SUSPEND_RESUME, &plat_priv->driver_state);
out:
	return ret;
}

static int cnss_pci_resume(struct device *dev)
static int cnss_pci_resume_bus(struct cnss_pci_data *pci_priv)
{
	struct pci_dev *pci_dev = pci_priv->pci_dev;
	int ret = 0;
	struct pci_dev *pci_dev = to_pci_dev(dev);
	struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
	struct cnss_plat_data *plat_priv;
	struct cnss_wlan_driver *driver_ops;

	if (!pci_priv)
		goto out;

	plat_priv = pci_priv->plat_priv;
	if (!plat_priv)
	if (pci_priv->pci_link_state == PCI_LINK_UP)
		goto out;

	if (pci_priv->pci_link_down_ind)
		goto out;

	if (!cnss_is_device_powered_on(pci_priv->plat_priv))
		goto out;

	if (pci_priv->pci_link_state == PCI_LINK_DOWN &&
	    !pci_priv->disable_pc) {
	if (cnss_set_pci_link(pci_priv, PCI_LINK_UP)) {
		cnss_fatal_err("Failed to resume PCI link from suspend\n");
			cnss_pci_link_down(dev);
		cnss_pci_link_down(&pci_dev->dev);
		ret = -EAGAIN;
		goto out;
	}
		pci_priv->pci_link_state = PCI_LINK_UP;

	if (pci_priv->drv_connected_last)
		goto skip_enable_pci;

	ret = pci_enable_device(pci_dev);
		if (ret)
	if (ret) {
		cnss_pr_err("Failed to enable PCI device, err = %d\n",
			    ret);
		goto out;
	}

	if (pci_priv->saved_state)
		cnss_set_pci_config_space(pci_priv,
@@ -1859,16 +1843,84 @@ static int cnss_pci_resume(struct device *dev)

skip_enable_pci:
	cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RESUME);
	pci_priv->pci_link_state = PCI_LINK_UP;
out:
	return ret;
}

	driver_ops = pci_priv->driver_ops;
	if (driver_ops && driver_ops->resume) {
		ret = driver_ops->resume(pci_dev);
static int cnss_pci_suspend(struct device *dev)
{
	int ret = 0;
	struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev));
	struct cnss_plat_data *plat_priv;

	if (!pci_priv)
		goto out;

	plat_priv = pci_priv->plat_priv;
	if (!plat_priv)
		goto out;

	if (!cnss_is_device_powered_on(plat_priv))
		goto out;

	set_bit(CNSS_IN_SUSPEND_RESUME, &plat_priv->driver_state);

	if (!test_bit(DISABLE_DRV, &plat_priv->ctrl_params.quirks))
		pci_priv->drv_connected_last =
			cnss_pci_get_drv_connected(pci_priv);

	ret = cnss_pci_suspend_driver(pci_priv);
	if (ret)
			cnss_pr_err("Failed to resume host driver, err = %d\n",
				    ret);
		goto clear_flag;

	if (!pci_priv->disable_pc) {
		ret = cnss_pci_suspend_bus(pci_priv);
		if (ret)
			goto resume_driver;
	}

	cnss_pci_set_monitor_wake_intr(pci_priv, false);

	return 0;

resume_driver:
	cnss_pci_resume_driver(pci_priv);
clear_flag:
	pci_priv->drv_connected_last = 0;
	clear_bit(CNSS_IN_SUSPEND_RESUME, &plat_priv->driver_state);
out:
	return ret;
}

static int cnss_pci_resume(struct device *dev)
{
	int ret = 0;
	struct pci_dev *pci_dev = to_pci_dev(dev);
	struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
	struct cnss_plat_data *plat_priv;

	if (!pci_priv)
		goto out;

	plat_priv = pci_priv->plat_priv;
	if (!plat_priv)
		goto out;

	if (pci_priv->pci_link_down_ind)
		goto out;

	if (!cnss_is_device_powered_on(pci_priv->plat_priv))
		goto out;

	if (!pci_priv->disable_pc) {
		ret = cnss_pci_resume_bus(pci_priv);
		if (ret)
			goto out;
	}

	ret = cnss_pci_resume_driver(pci_priv);

	pci_priv->drv_connected_last = 0;
	clear_bit(CNSS_IN_SUSPEND_RESUME, &plat_priv->driver_state);

@@ -2146,31 +2198,9 @@ int cnss_auto_suspend(struct device *dev)
	if (!plat_priv)
		return -ENODEV;

	if (pci_priv->pci_link_state == PCI_LINK_UP) {
		if (cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_SUSPEND)) {
			ret = -EAGAIN;
			goto out;
		}

		if (pci_priv->drv_connected_last)
			goto skip_disable_pci;

		pci_clear_master(pci_dev);
		cnss_set_pci_config_space(pci_priv, SAVE_PCI_CONFIG_SPACE);
		pci_disable_device(pci_dev);

		ret = pci_set_power_state(pci_dev, PCI_D3hot);
	ret = cnss_pci_suspend_bus(pci_priv);
	if (ret)
			cnss_pr_err("Failed to set D3Hot, err =  %d\n", ret);

skip_disable_pci:
		if (cnss_set_pci_link(pci_priv, PCI_LINK_DOWN)) {
			ret = -EAGAIN;
			goto resume_mhi;
		}

		pci_priv->pci_link_state = PCI_LINK_DOWN;
	}
		return ret;

	cnss_pci_set_auto_suspended(pci_priv, 1);
	cnss_pci_set_monitor_wake_intr(pci_priv, true);
@@ -2180,13 +2210,6 @@ int cnss_auto_suspend(struct device *dev)
					    CNSS_BUS_WIDTH_NONE);

	return 0;

resume_mhi:
	if (pci_enable_device(pci_dev))
		cnss_pr_err("Failed to enable PCI device!\n");
	cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RESUME);
out:
	return ret;
}
EXPORT_SYMBOL(cnss_auto_suspend);

@@ -2205,37 +2228,17 @@ int cnss_auto_resume(struct device *dev)
	if (!plat_priv)
		return -ENODEV;

	if (pci_priv->pci_link_state == PCI_LINK_DOWN) {
		if (cnss_set_pci_link(pci_priv, PCI_LINK_UP)) {
			cnss_fatal_err("Failed to resume PCI link from suspend\n");
			cnss_pci_link_down(dev);
			ret = -EAGAIN;
			goto out;
		}
		pci_priv->pci_link_state = PCI_LINK_UP;

		if (pci_priv->drv_connected_last)
			goto skip_enable_pci;

		ret = pci_enable_device(pci_dev);
	ret = cnss_pci_resume_bus(pci_priv);
	if (ret)
			cnss_pr_err("Failed to enable PCI device, err = %d\n",
				    ret);

		cnss_set_pci_config_space(pci_priv, RESTORE_PCI_CONFIG_SPACE);
		pci_set_master(pci_dev);

skip_enable_pci:
		cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RESUME);
	}
		return ret;

	cnss_pci_set_auto_suspended(pci_priv, 0);

	bus_bw_info = &plat_priv->bus_bw_info;
	msm_bus_scale_client_update_request(bus_bw_info->bus_client,
					    bus_bw_info->current_bw_vote);
out:
	return ret;

	return 0;
}
EXPORT_SYMBOL(cnss_auto_resume);