From 47b53726d86d544beb0180fe2e129c334c0c6ece Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Wed, 20 May 2020 17:13:19 -0700 Subject: [PATCH] cnss2: Set CNSS PM ops to PM domain Directly register CNSS PM ops to PM domain so that runtime PM core will avoid calling PCIe framework runtime PM callbacks. This is able to help CNSS driver sync runtime PM suspend/resume with any other PCIe bus suspend/resume requests. Change-Id: Ib71f0bf8eb8f28d1a4334d59505a24470a19a816 Signed-off-by: Yue Ma --- drivers/net/wireless/cnss2/main.c | 11 +++++++++++ drivers/net/wireless/cnss2/main.h | 1 + drivers/net/wireless/cnss2/pci.c | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index 44dad7fbcd55..9b0c35483556 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -2567,6 +2567,16 @@ static void cnss_init_control_params(struct cnss_plat_data *plat_priv) plat_priv->ctrl_params.time_sync_period = CNSS_TIME_SYNC_PERIOD_DEFAULT; } +static void cnss_get_pm_domain_info(struct cnss_plat_data *plat_priv) +{ + struct device *dev = &plat_priv->plat_dev->dev; + + plat_priv->use_pm_domain = + of_property_read_bool(dev->of_node, "use-pm-domain"); + + cnss_pr_dbg("use-pm-domain is %d\n", plat_priv->use_pm_domain); +} + static void cnss_get_wlaon_pwr_ctrl_info(struct cnss_plat_data *plat_priv) { struct device *dev = &plat_priv->plat_dev->dev; @@ -2656,6 +2666,7 @@ static int cnss_probe(struct platform_device *plat_dev) INIT_LIST_HEAD(&plat_priv->vreg_list); INIT_LIST_HEAD(&plat_priv->clk_list); + cnss_get_pm_domain_info(plat_priv); cnss_get_wlaon_pwr_ctrl_info(plat_priv); cnss_get_tcs_info(plat_priv); cnss_get_cpr_info(plat_priv); diff --git a/drivers/net/wireless/cnss2/main.h b/drivers/net/wireless/cnss2/main.h index 9e79766e71f1..d3ee83e1d523 100644 --- a/drivers/net/wireless/cnss2/main.h +++ b/drivers/net/wireless/cnss2/main.h @@ -421,6 +421,7 @@ struct cnss_plat_data { void *get_info_cb_ctx; int (*get_info_cb)(void *ctx, void *event, int event_len); bool cbc_enabled; + u8 use_pm_domain; u8 use_nv_mac; u8 set_wlaon_pwr_ctrl; struct cnss_tcs_info tcs_info; diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index 2d574ef9f3bb..76fdad5739d8 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -2670,6 +2670,10 @@ static int cnss_pci_suspend_noirq(struct device *dev) if (driver_ops && driver_ops->suspend_noirq) ret = driver_ops->suspend_noirq(pci_dev); + if (pci_priv->disable_pc && !pci_dev->state_saved && + !pci_priv->plat_priv->use_pm_domain) + pci_save_state(pci_dev); + out: return ret; } @@ -4617,6 +4621,22 @@ static void cnss_pci_config_regs(struct cnss_pci_data *pci_priv) } } +/* Setting to use this cnss_pm_domain ops will let PM framework override the + * ops from dev->bus->pm which is pci_dev_pm_ops from pci-driver.c. This ops + * has to take care everything device driver needed which is currently done + * from pci_dev_pm_ops. + */ +static struct dev_pm_domain cnss_pm_domain = { + .ops = { + SET_SYSTEM_SLEEP_PM_OPS(cnss_pci_suspend, cnss_pci_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cnss_pci_suspend_noirq, + cnss_pci_resume_noirq) + SET_RUNTIME_PM_OPS(cnss_pci_runtime_suspend, + cnss_pci_runtime_resume, + cnss_pci_runtime_idle) + } +}; + static int cnss_pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) { @@ -4646,6 +4666,8 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, plat_priv->device_id = pci_dev->device; plat_priv->bus_priv = pci_priv; mutex_init(&pci_priv->bus_lock); + if (plat_priv->use_pm_domain) + dev->pm_domain = &cnss_pm_domain; ret = of_reserved_mem_device_init(dev); if (ret)