From b2375e8ce9e4f2c8cf404e09dba10bc585427891 Mon Sep 17 00:00:00 2001 From: Arun Kumar Khandavalli Date: Mon, 28 Sep 2020 10:47:19 +0530 Subject: [PATCH] qcacld-3.0: Serialize psoc idle shutdown and restart via PLD Serialize psoc interface inactivity idle shutdown and restart via PLD such that platform driver can serialize psoc idle shutdown and restart to driver unload and SSR events to avoid any race conditions. Change-Id: I177a60eaf83b1c81f08cab2dc8a6bc1497484809 CRs-Fixed: 2776866 --- core/pld/src/pld_common.c | 88 ++++++++++++++++++++------------------- core/pld/src/pld_snoc.c | 41 ++++++++++++++++++ core/pld/src/pld_snoc.h | 20 +++++++++ 3 files changed, 107 insertions(+), 42 deletions(-) diff --git a/core/pld/src/pld_common.c b/core/pld/src/pld_common.c index bb1400066b09..2a1334be4f1e 100644 --- a/core/pld/src/pld_common.c +++ b/core/pld/src/pld_common.c @@ -2836,27 +2836,29 @@ int pld_idle_shutdown(struct device *dev, type = pld_get_bus_type(dev); switch (type) { - case PLD_BUS_TYPE_SDIO: - case PLD_BUS_TYPE_USB: - case PLD_BUS_TYPE_SNOC: - errno = shutdown_cb(dev); - break; - case PLD_BUS_TYPE_PCIE: - errno = pld_pcie_idle_shutdown(dev); - break; - case PLD_BUS_TYPE_PCIE_FW_SIM: - case PLD_BUS_TYPE_IPCI_FW_SIM: - errno = pld_pcie_fw_sim_idle_shutdown(dev); - break; - case PLD_BUS_TYPE_SNOC_FW_SIM: - errno = pld_snoc_fw_sim_idle_shutdown(dev); - break; - case PLD_BUS_TYPE_IPCI: - errno = pld_ipci_idle_shutdown(dev); - break; - default: - pr_err("Invalid device type %d\n", type); - break; + case PLD_BUS_TYPE_SDIO: + case PLD_BUS_TYPE_USB: + errno = shutdown_cb(dev); + break; + case PLD_BUS_TYPE_SNOC: + errno = pld_snoc_idle_shutdown(dev); + break; + case PLD_BUS_TYPE_PCIE: + errno = pld_pcie_idle_shutdown(dev); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_IPCI_FW_SIM: + errno = pld_pcie_fw_sim_idle_shutdown(dev); + break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + errno = pld_snoc_fw_sim_idle_shutdown(dev); + break; + case PLD_BUS_TYPE_IPCI: + errno = pld_ipci_idle_shutdown(dev); + break; + default: + pr_err("Invalid device type %d\n", type); + break; } return errno; @@ -2873,27 +2875,29 @@ int pld_idle_restart(struct device *dev, type = pld_get_bus_type(dev); switch (type) { - case PLD_BUS_TYPE_SDIO: - case PLD_BUS_TYPE_USB: - case PLD_BUS_TYPE_SNOC: - errno = restart_cb(dev); - break; - case PLD_BUS_TYPE_PCIE: - errno = pld_pcie_idle_restart(dev); - break; - case PLD_BUS_TYPE_PCIE_FW_SIM: - case PLD_BUS_TYPE_IPCI_FW_SIM: - errno = pld_pcie_fw_sim_idle_restart(dev); - break; - case PLD_BUS_TYPE_SNOC_FW_SIM: - errno = pld_snoc_fw_sim_idle_restart(dev); - break; - case PLD_BUS_TYPE_IPCI: - errno = pld_ipci_idle_restart(dev); - break; - default: - pr_err("Invalid device type %d\n", type); - break; + case PLD_BUS_TYPE_SDIO: + case PLD_BUS_TYPE_USB: + errno = restart_cb(dev); + break; + case PLD_BUS_TYPE_SNOC: + errno = pld_snoc_idle_restart(dev); + break; + case PLD_BUS_TYPE_PCIE: + errno = pld_pcie_idle_restart(dev); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_IPCI_FW_SIM: + errno = pld_pcie_fw_sim_idle_restart(dev); + break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + errno = pld_snoc_fw_sim_idle_restart(dev); + break; + case PLD_BUS_TYPE_IPCI: + errno = pld_ipci_idle_restart(dev); + break; + default: + pr_err("Invalid device type %d\n", type); + break; } return errno; diff --git a/core/pld/src/pld_snoc.c b/core/pld/src/pld_snoc.c index f6114240bdb6..4461c966896b 100644 --- a/core/pld/src/pld_snoc.c +++ b/core/pld/src/pld_snoc.c @@ -34,6 +34,45 @@ #include "osif_psoc_sync.h" #ifdef CONFIG_PLD_SNOC_ICNSS +/** + * pld_snoc_idle_restart_cb() - Perform idle restart + * @pdev: platform device + * + * This function will be called if there is an idle restart request + * + * Return: int + **/ +static int pld_snoc_idle_restart_cb(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->idle_restart) + return pld_context->ops->idle_restart(dev, PLD_BUS_TYPE_SNOC); + + return -ENODEV; +} + +/** + * pld_snoc_idle_shutdown_cb() - Perform idle shutdown + * @pdev: PCIE device + * @id: PCIE device ID + * + * This function will be called if there is an idle shutdown request + * + * Return: int + */ +static int pld_snoc_idle_shutdown_cb(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->shutdown) + return pld_context->ops->idle_shutdown(dev, PLD_BUS_TYPE_SNOC); + + return -ENODEV; +} + /** * pld_snoc_probe() - Probe function for platform driver * @dev: device @@ -357,6 +396,8 @@ struct icnss_driver_ops pld_snoc_ops = { .suspend_noirq = pld_snoc_suspend_noirq, .resume_noirq = pld_snoc_resume_noirq, .uevent = pld_snoc_uevent, + .idle_restart = pld_snoc_idle_restart_cb, + .idle_shutdown = pld_snoc_idle_shutdown_cb, }; /** diff --git a/core/pld/src/pld_snoc.h b/core/pld/src/pld_snoc.h index 7c938d518167..270ac1477a24 100644 --- a/core/pld/src/pld_snoc.h +++ b/core/pld/src/pld_snoc.h @@ -113,6 +113,16 @@ static inline void *pld_snoc_smmu_get_mapping(struct device *dev) } #endif +static inline int pld_snoc_idle_restart(struct device *dev) +{ + return 0; +} + +static inline int pld_snoc_idle_shutdown(struct device *dev) +{ + return 0; +} + static inline int pld_snoc_smmu_map(struct device *dev, phys_addr_t paddr, uint32_t *iova_addr, size_t size) { @@ -354,5 +364,15 @@ static inline void pld_snoc_block_shutdown(bool status) { icnss_block_shutdown(status); } + +static inline int pld_snoc_idle_restart(struct device *dev) +{ + return icnss_idle_restart(dev); +} + +static inline int pld_snoc_idle_shutdown(struct device *dev) +{ + return icnss_idle_shutdown(dev); +} #endif #endif