Loading drivers/net/wireless/cnss2/debug.c +20 −3 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #include <linux/err.h> #include <linux/seq_file.h> Loading @@ -11,8 +11,10 @@ #define MMIO_REG_ACCESS_MEM_TYPE 0xFF #if IS_ENABLED(CONFIG_IPC_LOGGING) void *cnss_ipc_log_context; void *cnss_ipc_log_long_context; #endif static int cnss_pin_connect_show(struct seq_file *s, void *data) { Loading Loading @@ -872,7 +874,8 @@ void cnss_debugfs_destroy(struct cnss_plat_data *plat_priv) } #endif int cnss_debug_init(void) #if IS_ENABLED(CONFIG_IPC_LOGGING) static int cnss_ipc_logging_init(void) { cnss_ipc_log_context = ipc_log_context_create(CNSS_IPC_LOG_PAGES, "cnss", 0); Loading @@ -892,7 +895,7 @@ int cnss_debug_init(void) return 0; } void cnss_debug_deinit(void) static void cnss_ipc_logging_deinit(void) { if (cnss_ipc_log_long_context) { ipc_log_context_destroy(cnss_ipc_log_long_context); Loading @@ -904,3 +907,17 @@ void cnss_debug_deinit(void) cnss_ipc_log_context = NULL; } } #else static int cnss_ipc_logging_init(void) { return 0; } static void cnss_ipc_logging_deinit(void) {} #endif int cnss_debug_init(void) { return cnss_ipc_logging_init(); } void cnss_debug_deinit(void) { cnss_ipc_logging_deinit(); } drivers/net/wireless/cnss2/debug.h +8 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #ifndef _CNSS_DEBUG_H #define _CNSS_DEBUG_H #if IS_ENABLED(CONFIG_IPC_LOGGING) #include <linux/ipc_logging.h> #endif #include <linux/printk.h> #if IS_ENABLED(CONFIG_IPC_LOGGING) #define CNSS_IPC_LOG_PAGES 32 extern void *cnss_ipc_log_context; Loading @@ -17,6 +20,10 @@ extern void *cnss_ipc_log_long_context; #define cnss_ipc_log_long_string(_x...) \ ipc_log_string(cnss_ipc_log_long_context, _x) #else #define cnss_ipc_log_string(_x...) #define cnss_ipc_log_long_string(_x...) #endif #define cnss_pr_err(_fmt, ...) do { \ printk("%scnss: " _fmt, KERN_ERR, ##__VA_ARGS__); \ Loading drivers/net/wireless/cnss2/main.c +41 −10 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #include <linux/delay.h> #include <linux/jiffies.h> Loading @@ -11,7 +11,9 @@ #include <linux/rwsem.h> #include <linux/suspend.h> #include <linux/timer.h> #if IS_ENABLED(CONFIG_QCOM_MINIDUMP) #include <soc/qcom/minidump.h> #endif #include "main.h" #include "bus.h" Loading Loading @@ -95,7 +97,7 @@ static struct notifier_block cnss_pm_notifier = { .notifier_call = cnss_pm_notify, }; static void cnss_pm_stay_awake(struct cnss_plat_data *plat_priv) void cnss_pm_stay_awake(struct cnss_plat_data *plat_priv) { if (atomic_inc_return(&plat_priv->pm_count) != 1) return; Loading @@ -106,7 +108,7 @@ static void cnss_pm_stay_awake(struct cnss_plat_data *plat_priv) pm_stay_awake(&plat_priv->plat_dev->dev); } static void cnss_pm_relax(struct cnss_plat_data *plat_priv) void cnss_pm_relax(struct cnss_plat_data *plat_priv) { int r = atomic_dec_return(&plat_priv->pm_count); Loading Loading @@ -1980,6 +1982,7 @@ void cnss_unregister_subsys(struct cnss_plat_data *plat_priv) cnss_pr_err("Failed to unregister panic handler\n"); } #if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2) static void *cnss_create_ramdump_device(struct cnss_plat_data *plat_priv) { return &plat_priv->plat_dev->dev; Loading @@ -1989,6 +1992,7 @@ static void cnss_destroy_ramdump_device(struct cnss_plat_data *plat_priv, void *ramdump_dev) { } #endif #if IS_ENABLED(CONFIG_SUBSYSTEM_RAMDUMP) int cnss_do_ramdump(struct cnss_plat_data *plat_priv) Loading Loading @@ -2071,6 +2075,7 @@ int cnss_do_elf_ramdump(struct cnss_plat_data *plat_priv) #endif /* CONFIG_SUBSYSTEM_RAMDUMP */ #endif /* CONFIG_MSM_SUBSYSTEM_RESTART */ #if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2) static int cnss_init_dump_entry(struct cnss_plat_data *plat_priv) { struct cnss_ramdump_info *ramdump_info; Loading Loading @@ -2167,17 +2172,10 @@ static void cnss_unregister_ramdump_v1(struct cnss_plat_data *plat_priv) * * Return: Same given error code if mem dump feature enabled, 0 otherwise */ #ifdef CONFIG_QCOM_MEMORY_DUMP_V2 static int cnss_ignore_dump_data_reg_fail(int ret) { return ret; } #else static int cnss_ignore_dump_data_reg_fail(int ret) { return 0; } #endif static int cnss_register_ramdump_v2(struct cnss_plat_data *plat_priv) { Loading Loading @@ -2287,7 +2285,16 @@ void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv) break; } } #else int cnss_register_ramdump(struct cnss_plat_data *plat_priv) { return 0; } void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv) {} #endif /* CONFIG_QCOM_MEMORY_DUMP_V2 */ #if IS_ENABLED(CONFIG_QCOM_MINIDUMP) int cnss_minidump_add_region(struct cnss_plat_data *plat_priv, enum cnss_fw_dump_type type, int seg_no, void *va, phys_addr_t pa, size_t size) Loading Loading @@ -2368,7 +2375,23 @@ int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv, return ret; } #else int cnss_minidump_add_region(struct cnss_plat_data *plat_priv, enum cnss_fw_dump_type type, int seg_no, void *va, phys_addr_t pa, size_t size) { return 0; } int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv, enum cnss_fw_dump_type type, int seg_no, void *va, phys_addr_t pa, size_t size) { return 0; } #endif /* CONFIG_QCOM_MINIDUMP */ #if IS_ENABLED(CONFIG_INTERCONNECT) /** * cnss_register_bus_scale() - Setup interconnect voting data * @plat_priv: Platform data structure Loading Loading @@ -2494,6 +2517,14 @@ static void cnss_unregister_bus_scale(struct cnss_plat_data *plat_priv) } memset(&plat_priv->icc, 0, sizeof(plat_priv->icc)); } #else static int cnss_register_bus_scale(struct cnss_plat_data *plat_priv) { return 0; } static void cnss_unregister_bus_scale(struct cnss_plat_data *plat_priv) {} #endif /* CONFIG_INTERCONNECT */ static ssize_t recovery_store(struct device *dev, struct device_attribute *attr, Loading drivers/net/wireless/cnss2/main.h +11 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #ifndef _CNSS_MAIN_H #define _CNSS_MAIN_H Loading @@ -9,11 +9,15 @@ #include <linux/esoc_client.h> #endif #include <linux/etherdevice.h> #if IS_ENABLED(CONFIG_INTERCONNECT) #include <linux/interconnect.h> #endif #include <linux/pm_qos.h> #include <linux/platform_device.h> #include <net/cnss2.h> #if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2) #include <soc/qcom/memory_dump.h> #endif #if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART) || \ IS_ENABLED(CONFIG_SUBSYSTEM_RAMDUMP) #include <soc/qcom/ramdump.h> Loading Loading @@ -106,7 +110,9 @@ struct cnss_ramdump_info { unsigned long ramdump_size; void *ramdump_va; phys_addr_t ramdump_pa; #if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2) struct msm_dump_data dump_data; #endif }; struct cnss_dump_seg { Loading Loading @@ -142,6 +148,7 @@ struct cnss_esoc_info { }; #endif #if IS_ENABLED(CONFIG_INTERCONNECT) /** * struct cnss_bus_bw_cfg - Interconnect vote data * @avg_bw: Vote for average bandwidth Loading @@ -168,6 +175,7 @@ struct cnss_bus_bw_info { struct icc_path *icc_path; struct cnss_bus_bw_cfg *cfg_table; }; #endif /** * struct cnss_interconnect_cfg - CNSS platform interconnect config Loading Loading @@ -505,6 +513,8 @@ static inline u64 cnss_get_host_timestamp(struct cnss_plat_data *plat_priv) #endif struct cnss_plat_data *cnss_get_plat_priv(struct platform_device *plat_dev); void cnss_pm_stay_awake(struct cnss_plat_data *plat_priv); void cnss_pm_relax(struct cnss_plat_data *plat_priv); int cnss_driver_event_post(struct cnss_plat_data *plat_priv, enum cnss_driver_event_type type, u32 flags, void *data); Loading drivers/net/wireless/cnss2/pci.c +202 −24 Original line number Diff line number Diff line Loading @@ -8,8 +8,10 @@ #include <linux/module.h> #include <linux/msi.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/of_reserved_mem.h> #include <linux/pm_runtime.h> #include <linux/suspend.h> #include <linux/memblock.h> #include <linux/completion.h> Loading Loading @@ -527,6 +529,7 @@ static int cnss_pci_force_wake_put(struct cnss_pci_data *pci_priv) return ret; } #if IS_ENABLED(CONFIG_INTERCONNECT) /** * cnss_setup_bus_bandwidth() - Setup interconnect vote for given bandwidth * @plat_priv: Platform private data struct Loading Loading @@ -580,6 +583,18 @@ int cnss_request_bus_bandwidth(struct device *dev, int bandwidth) return cnss_setup_bus_bandwidth(plat_priv, (u32)bandwidth, true); } #else static int cnss_setup_bus_bandwidth(struct cnss_plat_data *plat_priv, u32 bw, bool save) { return 0; } int cnss_request_bus_bandwidth(struct device *dev, int bandwidth) { return 0; } #endif EXPORT_SYMBOL(cnss_request_bus_bandwidth); int cnss_pci_debug_reg_read(struct cnss_pci_data *pci_priv, u32 offset, Loading Loading @@ -4908,6 +4923,42 @@ static int cnss_mhi_bw_scale(struct mhi_controller *mhi_ctrl, return 0; } #if IS_ENABLED(CONFIG_IPC_LOGGING) static int cnss_pci_mhi_ipc_logging_init(struct cnss_pci_data *pci_priv) { struct mhi_controller *mhi_ctrl = pci_priv->mhi_ctrl; mhi_ctrl->log_buf = ipc_log_context_create(CNSS_IPC_LOG_PAGES, "cnss-mhi", 0); if (!mhi_ctrl->log_buf) cnss_pr_err("Unable to create CNSS MHI IPC log context\n"); mhi_ctrl->cntrl_log_buf = ipc_log_context_create(CNSS_IPC_LOG_PAGES, "cnss-mhi-cntrl", 0); if (!mhi_ctrl->cntrl_log_buf) cnss_pr_err("Unable to create CNSS MHICNTRL IPC log context\n"); return 0; } static void cnss_pci_mhi_ipc_logging_deinit(struct cnss_pci_data *pci_priv) { struct mhi_controller *mhi_ctrl = pci_priv->mhi_ctrl; if (mhi_ctrl->log_buf) ipc_log_context_destroy(mhi_ctrl->log_buf); if (mhi_ctrl->cntrl_log_buf) ipc_log_context_destroy(mhi_ctrl->cntrl_log_buf); } #else static int cnss_pci_mhi_ipc_logging_init(struct cnss_pci_data *pci_priv) { return 0; } static void cnss_pci_mhi_ipc_logging_deinit(struct cnss_pci_data *pci_priv) {} #endif static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv) { int ret = 0; Loading Loading @@ -4972,15 +5023,7 @@ static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv) mhi_ctrl->fbc_download = true; mhi_ctrl->rddm_supported = true; mhi_ctrl->log_buf = ipc_log_context_create(CNSS_IPC_LOG_PAGES, "cnss-mhi", 0); if (!mhi_ctrl->log_buf) cnss_pr_err("Unable to create CNSS MHI IPC log context\n"); mhi_ctrl->cntrl_log_buf = ipc_log_context_create(CNSS_IPC_LOG_PAGES, "cnss-mhi-cntrl", 0); if (!mhi_ctrl->cntrl_log_buf) cnss_pr_err("Unable to create CNSS MHICNTRL IPC log context\n"); cnss_pci_mhi_ipc_logging_init(pci_priv); ret = of_register_mhi_controller(mhi_ctrl); if (ret) { Loading @@ -4997,10 +5040,7 @@ static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv) unreg_mhi: mhi_unregister_mhi_controller(mhi_ctrl); destroy_ipc: if (mhi_ctrl->log_buf) ipc_log_context_destroy(mhi_ctrl->log_buf); if (mhi_ctrl->cntrl_log_buf) ipc_log_context_destroy(mhi_ctrl->cntrl_log_buf); cnss_pci_mhi_ipc_logging_deinit(pci_priv); kfree(mhi_ctrl->irq); free_mhi_ctrl: mhi_free_controller(mhi_ctrl); Loading @@ -5016,10 +5056,7 @@ static void cnss_pci_unregister_mhi(struct cnss_pci_data *pci_priv) return; mhi_unregister_mhi_controller(mhi_ctrl); if (mhi_ctrl->log_buf) ipc_log_context_destroy(mhi_ctrl->log_buf); if (mhi_ctrl->cntrl_log_buf) ipc_log_context_destroy(mhi_ctrl->cntrl_log_buf); cnss_pci_mhi_ipc_logging_deinit(pci_priv); kfree(mhi_ctrl->irq); mhi_free_controller(mhi_ctrl); } Loading Loading @@ -5049,6 +5086,151 @@ static void cnss_pci_config_regs(struct cnss_pci_data *pci_priv) } } #if !IS_ENABLED(CONFIG_ARCH_QCOM) static irqreturn_t cnss_pci_wake_handler(int irq, void *data) { struct cnss_pci_data *pci_priv = data; struct cnss_plat_data *plat_priv = pci_priv->plat_priv; pci_priv->wake_counter++; cnss_pr_dbg("WLAN PCI wake IRQ (%u) is asserted #%u\n", pci_priv->wake_irq, pci_priv->wake_counter); /* Make sure abort current suspend */ cnss_pm_stay_awake(plat_priv); cnss_pm_relax(plat_priv); /* Above two pm* API calls will abort system suspend only when * plat_dev->dev->ws is initiated by device_init_wakeup() API, and * calling pm_system_wakeup() is just to guarantee system suspend * can be aborted if it is not initiated in any case. */ pm_system_wakeup(); complete(&pci_priv->wake_event); if (cnss_pci_get_monitor_wake_intr(pci_priv) && cnss_pci_get_auto_suspended(pci_priv)) { cnss_pci_set_monitor_wake_intr(pci_priv, false); cnss_pci_pm_request_resume(pci_priv); } return IRQ_HANDLED; } /** * cnss_pci_wake_gpio_init() - Setup PCI wake GPIO for WLAN * @pci_priv: driver PCI bus context pointer * * This function initializes WLAN PCI wake GPIO and corresponding * interrupt. It should be used in non-MSM platforms whose PCIe * root complex driver doesn't handle the GPIO. * * Return: 0 for success or skip, negative value for error */ static int cnss_pci_wake_gpio_init(struct cnss_pci_data *pci_priv) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct device *dev = &plat_priv->plat_dev->dev; int ret = 0; pci_priv->wake_gpio = of_get_named_gpio(dev->of_node, "wlan-pci-wake-gpio", 0); if (pci_priv->wake_gpio < 0) goto out; cnss_pr_dbg("Get PCI wake GPIO (%d) from device node\n", pci_priv->wake_gpio); ret = gpio_request(pci_priv->wake_gpio, "wlan_pci_wake_gpio"); if (ret) { cnss_pr_err("Failed to request PCI wake GPIO, err = %d\n", ret); goto out; } gpio_direction_input(pci_priv->wake_gpio); pci_priv->wake_irq = gpio_to_irq(pci_priv->wake_gpio); ret = request_irq(pci_priv->wake_irq, cnss_pci_wake_handler, IRQF_TRIGGER_FALLING, "wlan_pci_wake_irq", pci_priv); if (ret) { cnss_pr_err("Failed to request PCI wake IRQ, err = %d\n", ret); goto free_gpio; } ret = enable_irq_wake(pci_priv->wake_irq); if (ret) { cnss_pr_err("Failed to enable PCI wake IRQ, err = %d\n", ret); goto free_irq; } return 0; free_irq: free_irq(pci_priv->wake_irq, pci_priv); free_gpio: gpio_free(pci_priv->wake_irq); out: return ret; } static void cnss_pci_wake_gpio_deinit(struct cnss_pci_data *pci_priv) { if (pci_priv->wake_irq < 0) return; disable_irq_wake(pci_priv->wake_irq); free_irq(pci_priv->wake_irq, pci_priv); gpio_free(pci_priv->wake_irq); } #else static int cnss_pci_wake_gpio_init(struct cnss_pci_data *pci_priv) { return 0; } static void cnss_pci_wake_gpio_deinit(struct cnss_pci_data *pci_priv) { } #endif #if IS_ENABLED(CONFIG_ARCH_QCOM) /** * cnss_pci_of_reserved_mem_device_init() - Assign reserved memory region * to given PCI device * @pci_priv: driver PCI bus context pointer * * This function shall call corresponding of_reserved_mem_device* API to * assign reserved memory region to PCI device based on where the memory is * defined and attached to (platform device of_node or PCI device of_node) * in device tree. * * Return: 0 for success, negative value for error */ static int cnss_pci_of_reserved_mem_device_init(struct cnss_pci_data *pci_priv) { struct device *dev_pci = &pci_priv->pci_dev->dev; int ret; /* Use of_reserved_mem_device_init_by_idx() if reserved memory is * attached to platform device of_node. */ ret = of_reserved_mem_device_init(dev_pci); if (ret) cnss_pr_err("Failed to init reserved mem device, err = %d\n", ret); if (dev_pci->cma_area) cnss_pr_dbg("CMA area is %s\n", cma_get_name(dev_pci->cma_area)); return ret; } #else static int cnss_pci_of_reserved_mem_device_init(struct cnss_pci_data *pci_priv) { return 0; } #endif /* 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 Loading Loading @@ -5097,12 +5279,7 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, if (plat_priv->use_pm_domain) dev->pm_domain = &cnss_pm_domain; ret = of_reserved_mem_device_init(dev); if (ret) cnss_pr_err("Failed to init reserved mem device, err = %d\n", ret); if (dev->cma_area) cnss_pr_dbg("CMA area is %s\n", cma_get_name(dev->cma_area)); cnss_pci_of_reserved_mem_device_init(pci_priv); ret = cnss_register_subsys(plat_priv); if (ret) Loading Loading @@ -5151,6 +5328,7 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, cnss_pci_time_sync_work_hdlr); cnss_pci_get_link_status(pci_priv); cnss_pci_set_wlaon_pwr_ctrl(pci_priv, false, true, false); cnss_pci_wake_gpio_init(pci_priv); break; default: cnss_pr_err("Unknown PCI device found: 0x%x\n", Loading Loading @@ -5204,6 +5382,7 @@ static void cnss_pci_remove(struct pci_dev *pci_dev) case QCA6390_DEVICE_ID: case QCA6490_DEVICE_ID: case WCN7850_DEVICE_ID: cnss_pci_wake_gpio_deinit(pci_priv); complete_all(&pci_priv->wake_event); del_timer(&pci_priv->dev_rddm_timer); break; Loading @@ -5223,7 +5402,6 @@ static void cnss_pci_remove(struct pci_dev *pci_dev) } else { cnss_pr_err("Plat_priv is null, Unable to unregister ramdump,subsys\n"); } } static const struct pci_device_id cnss_pci_id_table[] = { Loading Loading
drivers/net/wireless/cnss2/debug.c +20 −3 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #include <linux/err.h> #include <linux/seq_file.h> Loading @@ -11,8 +11,10 @@ #define MMIO_REG_ACCESS_MEM_TYPE 0xFF #if IS_ENABLED(CONFIG_IPC_LOGGING) void *cnss_ipc_log_context; void *cnss_ipc_log_long_context; #endif static int cnss_pin_connect_show(struct seq_file *s, void *data) { Loading Loading @@ -872,7 +874,8 @@ void cnss_debugfs_destroy(struct cnss_plat_data *plat_priv) } #endif int cnss_debug_init(void) #if IS_ENABLED(CONFIG_IPC_LOGGING) static int cnss_ipc_logging_init(void) { cnss_ipc_log_context = ipc_log_context_create(CNSS_IPC_LOG_PAGES, "cnss", 0); Loading @@ -892,7 +895,7 @@ int cnss_debug_init(void) return 0; } void cnss_debug_deinit(void) static void cnss_ipc_logging_deinit(void) { if (cnss_ipc_log_long_context) { ipc_log_context_destroy(cnss_ipc_log_long_context); Loading @@ -904,3 +907,17 @@ void cnss_debug_deinit(void) cnss_ipc_log_context = NULL; } } #else static int cnss_ipc_logging_init(void) { return 0; } static void cnss_ipc_logging_deinit(void) {} #endif int cnss_debug_init(void) { return cnss_ipc_logging_init(); } void cnss_debug_deinit(void) { cnss_ipc_logging_deinit(); }
drivers/net/wireless/cnss2/debug.h +8 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #ifndef _CNSS_DEBUG_H #define _CNSS_DEBUG_H #if IS_ENABLED(CONFIG_IPC_LOGGING) #include <linux/ipc_logging.h> #endif #include <linux/printk.h> #if IS_ENABLED(CONFIG_IPC_LOGGING) #define CNSS_IPC_LOG_PAGES 32 extern void *cnss_ipc_log_context; Loading @@ -17,6 +20,10 @@ extern void *cnss_ipc_log_long_context; #define cnss_ipc_log_long_string(_x...) \ ipc_log_string(cnss_ipc_log_long_context, _x) #else #define cnss_ipc_log_string(_x...) #define cnss_ipc_log_long_string(_x...) #endif #define cnss_pr_err(_fmt, ...) do { \ printk("%scnss: " _fmt, KERN_ERR, ##__VA_ARGS__); \ Loading
drivers/net/wireless/cnss2/main.c +41 −10 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #include <linux/delay.h> #include <linux/jiffies.h> Loading @@ -11,7 +11,9 @@ #include <linux/rwsem.h> #include <linux/suspend.h> #include <linux/timer.h> #if IS_ENABLED(CONFIG_QCOM_MINIDUMP) #include <soc/qcom/minidump.h> #endif #include "main.h" #include "bus.h" Loading Loading @@ -95,7 +97,7 @@ static struct notifier_block cnss_pm_notifier = { .notifier_call = cnss_pm_notify, }; static void cnss_pm_stay_awake(struct cnss_plat_data *plat_priv) void cnss_pm_stay_awake(struct cnss_plat_data *plat_priv) { if (atomic_inc_return(&plat_priv->pm_count) != 1) return; Loading @@ -106,7 +108,7 @@ static void cnss_pm_stay_awake(struct cnss_plat_data *plat_priv) pm_stay_awake(&plat_priv->plat_dev->dev); } static void cnss_pm_relax(struct cnss_plat_data *plat_priv) void cnss_pm_relax(struct cnss_plat_data *plat_priv) { int r = atomic_dec_return(&plat_priv->pm_count); Loading Loading @@ -1980,6 +1982,7 @@ void cnss_unregister_subsys(struct cnss_plat_data *plat_priv) cnss_pr_err("Failed to unregister panic handler\n"); } #if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2) static void *cnss_create_ramdump_device(struct cnss_plat_data *plat_priv) { return &plat_priv->plat_dev->dev; Loading @@ -1989,6 +1992,7 @@ static void cnss_destroy_ramdump_device(struct cnss_plat_data *plat_priv, void *ramdump_dev) { } #endif #if IS_ENABLED(CONFIG_SUBSYSTEM_RAMDUMP) int cnss_do_ramdump(struct cnss_plat_data *plat_priv) Loading Loading @@ -2071,6 +2075,7 @@ int cnss_do_elf_ramdump(struct cnss_plat_data *plat_priv) #endif /* CONFIG_SUBSYSTEM_RAMDUMP */ #endif /* CONFIG_MSM_SUBSYSTEM_RESTART */ #if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2) static int cnss_init_dump_entry(struct cnss_plat_data *plat_priv) { struct cnss_ramdump_info *ramdump_info; Loading Loading @@ -2167,17 +2172,10 @@ static void cnss_unregister_ramdump_v1(struct cnss_plat_data *plat_priv) * * Return: Same given error code if mem dump feature enabled, 0 otherwise */ #ifdef CONFIG_QCOM_MEMORY_DUMP_V2 static int cnss_ignore_dump_data_reg_fail(int ret) { return ret; } #else static int cnss_ignore_dump_data_reg_fail(int ret) { return 0; } #endif static int cnss_register_ramdump_v2(struct cnss_plat_data *plat_priv) { Loading Loading @@ -2287,7 +2285,16 @@ void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv) break; } } #else int cnss_register_ramdump(struct cnss_plat_data *plat_priv) { return 0; } void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv) {} #endif /* CONFIG_QCOM_MEMORY_DUMP_V2 */ #if IS_ENABLED(CONFIG_QCOM_MINIDUMP) int cnss_minidump_add_region(struct cnss_plat_data *plat_priv, enum cnss_fw_dump_type type, int seg_no, void *va, phys_addr_t pa, size_t size) Loading Loading @@ -2368,7 +2375,23 @@ int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv, return ret; } #else int cnss_minidump_add_region(struct cnss_plat_data *plat_priv, enum cnss_fw_dump_type type, int seg_no, void *va, phys_addr_t pa, size_t size) { return 0; } int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv, enum cnss_fw_dump_type type, int seg_no, void *va, phys_addr_t pa, size_t size) { return 0; } #endif /* CONFIG_QCOM_MINIDUMP */ #if IS_ENABLED(CONFIG_INTERCONNECT) /** * cnss_register_bus_scale() - Setup interconnect voting data * @plat_priv: Platform data structure Loading Loading @@ -2494,6 +2517,14 @@ static void cnss_unregister_bus_scale(struct cnss_plat_data *plat_priv) } memset(&plat_priv->icc, 0, sizeof(plat_priv->icc)); } #else static int cnss_register_bus_scale(struct cnss_plat_data *plat_priv) { return 0; } static void cnss_unregister_bus_scale(struct cnss_plat_data *plat_priv) {} #endif /* CONFIG_INTERCONNECT */ static ssize_t recovery_store(struct device *dev, struct device_attribute *attr, Loading
drivers/net/wireless/cnss2/main.h +11 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #ifndef _CNSS_MAIN_H #define _CNSS_MAIN_H Loading @@ -9,11 +9,15 @@ #include <linux/esoc_client.h> #endif #include <linux/etherdevice.h> #if IS_ENABLED(CONFIG_INTERCONNECT) #include <linux/interconnect.h> #endif #include <linux/pm_qos.h> #include <linux/platform_device.h> #include <net/cnss2.h> #if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2) #include <soc/qcom/memory_dump.h> #endif #if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART) || \ IS_ENABLED(CONFIG_SUBSYSTEM_RAMDUMP) #include <soc/qcom/ramdump.h> Loading Loading @@ -106,7 +110,9 @@ struct cnss_ramdump_info { unsigned long ramdump_size; void *ramdump_va; phys_addr_t ramdump_pa; #if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2) struct msm_dump_data dump_data; #endif }; struct cnss_dump_seg { Loading Loading @@ -142,6 +148,7 @@ struct cnss_esoc_info { }; #endif #if IS_ENABLED(CONFIG_INTERCONNECT) /** * struct cnss_bus_bw_cfg - Interconnect vote data * @avg_bw: Vote for average bandwidth Loading @@ -168,6 +175,7 @@ struct cnss_bus_bw_info { struct icc_path *icc_path; struct cnss_bus_bw_cfg *cfg_table; }; #endif /** * struct cnss_interconnect_cfg - CNSS platform interconnect config Loading Loading @@ -505,6 +513,8 @@ static inline u64 cnss_get_host_timestamp(struct cnss_plat_data *plat_priv) #endif struct cnss_plat_data *cnss_get_plat_priv(struct platform_device *plat_dev); void cnss_pm_stay_awake(struct cnss_plat_data *plat_priv); void cnss_pm_relax(struct cnss_plat_data *plat_priv); int cnss_driver_event_post(struct cnss_plat_data *plat_priv, enum cnss_driver_event_type type, u32 flags, void *data); Loading
drivers/net/wireless/cnss2/pci.c +202 −24 Original line number Diff line number Diff line Loading @@ -8,8 +8,10 @@ #include <linux/module.h> #include <linux/msi.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/of_reserved_mem.h> #include <linux/pm_runtime.h> #include <linux/suspend.h> #include <linux/memblock.h> #include <linux/completion.h> Loading Loading @@ -527,6 +529,7 @@ static int cnss_pci_force_wake_put(struct cnss_pci_data *pci_priv) return ret; } #if IS_ENABLED(CONFIG_INTERCONNECT) /** * cnss_setup_bus_bandwidth() - Setup interconnect vote for given bandwidth * @plat_priv: Platform private data struct Loading Loading @@ -580,6 +583,18 @@ int cnss_request_bus_bandwidth(struct device *dev, int bandwidth) return cnss_setup_bus_bandwidth(plat_priv, (u32)bandwidth, true); } #else static int cnss_setup_bus_bandwidth(struct cnss_plat_data *plat_priv, u32 bw, bool save) { return 0; } int cnss_request_bus_bandwidth(struct device *dev, int bandwidth) { return 0; } #endif EXPORT_SYMBOL(cnss_request_bus_bandwidth); int cnss_pci_debug_reg_read(struct cnss_pci_data *pci_priv, u32 offset, Loading Loading @@ -4908,6 +4923,42 @@ static int cnss_mhi_bw_scale(struct mhi_controller *mhi_ctrl, return 0; } #if IS_ENABLED(CONFIG_IPC_LOGGING) static int cnss_pci_mhi_ipc_logging_init(struct cnss_pci_data *pci_priv) { struct mhi_controller *mhi_ctrl = pci_priv->mhi_ctrl; mhi_ctrl->log_buf = ipc_log_context_create(CNSS_IPC_LOG_PAGES, "cnss-mhi", 0); if (!mhi_ctrl->log_buf) cnss_pr_err("Unable to create CNSS MHI IPC log context\n"); mhi_ctrl->cntrl_log_buf = ipc_log_context_create(CNSS_IPC_LOG_PAGES, "cnss-mhi-cntrl", 0); if (!mhi_ctrl->cntrl_log_buf) cnss_pr_err("Unable to create CNSS MHICNTRL IPC log context\n"); return 0; } static void cnss_pci_mhi_ipc_logging_deinit(struct cnss_pci_data *pci_priv) { struct mhi_controller *mhi_ctrl = pci_priv->mhi_ctrl; if (mhi_ctrl->log_buf) ipc_log_context_destroy(mhi_ctrl->log_buf); if (mhi_ctrl->cntrl_log_buf) ipc_log_context_destroy(mhi_ctrl->cntrl_log_buf); } #else static int cnss_pci_mhi_ipc_logging_init(struct cnss_pci_data *pci_priv) { return 0; } static void cnss_pci_mhi_ipc_logging_deinit(struct cnss_pci_data *pci_priv) {} #endif static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv) { int ret = 0; Loading Loading @@ -4972,15 +5023,7 @@ static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv) mhi_ctrl->fbc_download = true; mhi_ctrl->rddm_supported = true; mhi_ctrl->log_buf = ipc_log_context_create(CNSS_IPC_LOG_PAGES, "cnss-mhi", 0); if (!mhi_ctrl->log_buf) cnss_pr_err("Unable to create CNSS MHI IPC log context\n"); mhi_ctrl->cntrl_log_buf = ipc_log_context_create(CNSS_IPC_LOG_PAGES, "cnss-mhi-cntrl", 0); if (!mhi_ctrl->cntrl_log_buf) cnss_pr_err("Unable to create CNSS MHICNTRL IPC log context\n"); cnss_pci_mhi_ipc_logging_init(pci_priv); ret = of_register_mhi_controller(mhi_ctrl); if (ret) { Loading @@ -4997,10 +5040,7 @@ static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv) unreg_mhi: mhi_unregister_mhi_controller(mhi_ctrl); destroy_ipc: if (mhi_ctrl->log_buf) ipc_log_context_destroy(mhi_ctrl->log_buf); if (mhi_ctrl->cntrl_log_buf) ipc_log_context_destroy(mhi_ctrl->cntrl_log_buf); cnss_pci_mhi_ipc_logging_deinit(pci_priv); kfree(mhi_ctrl->irq); free_mhi_ctrl: mhi_free_controller(mhi_ctrl); Loading @@ -5016,10 +5056,7 @@ static void cnss_pci_unregister_mhi(struct cnss_pci_data *pci_priv) return; mhi_unregister_mhi_controller(mhi_ctrl); if (mhi_ctrl->log_buf) ipc_log_context_destroy(mhi_ctrl->log_buf); if (mhi_ctrl->cntrl_log_buf) ipc_log_context_destroy(mhi_ctrl->cntrl_log_buf); cnss_pci_mhi_ipc_logging_deinit(pci_priv); kfree(mhi_ctrl->irq); mhi_free_controller(mhi_ctrl); } Loading Loading @@ -5049,6 +5086,151 @@ static void cnss_pci_config_regs(struct cnss_pci_data *pci_priv) } } #if !IS_ENABLED(CONFIG_ARCH_QCOM) static irqreturn_t cnss_pci_wake_handler(int irq, void *data) { struct cnss_pci_data *pci_priv = data; struct cnss_plat_data *plat_priv = pci_priv->plat_priv; pci_priv->wake_counter++; cnss_pr_dbg("WLAN PCI wake IRQ (%u) is asserted #%u\n", pci_priv->wake_irq, pci_priv->wake_counter); /* Make sure abort current suspend */ cnss_pm_stay_awake(plat_priv); cnss_pm_relax(plat_priv); /* Above two pm* API calls will abort system suspend only when * plat_dev->dev->ws is initiated by device_init_wakeup() API, and * calling pm_system_wakeup() is just to guarantee system suspend * can be aborted if it is not initiated in any case. */ pm_system_wakeup(); complete(&pci_priv->wake_event); if (cnss_pci_get_monitor_wake_intr(pci_priv) && cnss_pci_get_auto_suspended(pci_priv)) { cnss_pci_set_monitor_wake_intr(pci_priv, false); cnss_pci_pm_request_resume(pci_priv); } return IRQ_HANDLED; } /** * cnss_pci_wake_gpio_init() - Setup PCI wake GPIO for WLAN * @pci_priv: driver PCI bus context pointer * * This function initializes WLAN PCI wake GPIO and corresponding * interrupt. It should be used in non-MSM platforms whose PCIe * root complex driver doesn't handle the GPIO. * * Return: 0 for success or skip, negative value for error */ static int cnss_pci_wake_gpio_init(struct cnss_pci_data *pci_priv) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct device *dev = &plat_priv->plat_dev->dev; int ret = 0; pci_priv->wake_gpio = of_get_named_gpio(dev->of_node, "wlan-pci-wake-gpio", 0); if (pci_priv->wake_gpio < 0) goto out; cnss_pr_dbg("Get PCI wake GPIO (%d) from device node\n", pci_priv->wake_gpio); ret = gpio_request(pci_priv->wake_gpio, "wlan_pci_wake_gpio"); if (ret) { cnss_pr_err("Failed to request PCI wake GPIO, err = %d\n", ret); goto out; } gpio_direction_input(pci_priv->wake_gpio); pci_priv->wake_irq = gpio_to_irq(pci_priv->wake_gpio); ret = request_irq(pci_priv->wake_irq, cnss_pci_wake_handler, IRQF_TRIGGER_FALLING, "wlan_pci_wake_irq", pci_priv); if (ret) { cnss_pr_err("Failed to request PCI wake IRQ, err = %d\n", ret); goto free_gpio; } ret = enable_irq_wake(pci_priv->wake_irq); if (ret) { cnss_pr_err("Failed to enable PCI wake IRQ, err = %d\n", ret); goto free_irq; } return 0; free_irq: free_irq(pci_priv->wake_irq, pci_priv); free_gpio: gpio_free(pci_priv->wake_irq); out: return ret; } static void cnss_pci_wake_gpio_deinit(struct cnss_pci_data *pci_priv) { if (pci_priv->wake_irq < 0) return; disable_irq_wake(pci_priv->wake_irq); free_irq(pci_priv->wake_irq, pci_priv); gpio_free(pci_priv->wake_irq); } #else static int cnss_pci_wake_gpio_init(struct cnss_pci_data *pci_priv) { return 0; } static void cnss_pci_wake_gpio_deinit(struct cnss_pci_data *pci_priv) { } #endif #if IS_ENABLED(CONFIG_ARCH_QCOM) /** * cnss_pci_of_reserved_mem_device_init() - Assign reserved memory region * to given PCI device * @pci_priv: driver PCI bus context pointer * * This function shall call corresponding of_reserved_mem_device* API to * assign reserved memory region to PCI device based on where the memory is * defined and attached to (platform device of_node or PCI device of_node) * in device tree. * * Return: 0 for success, negative value for error */ static int cnss_pci_of_reserved_mem_device_init(struct cnss_pci_data *pci_priv) { struct device *dev_pci = &pci_priv->pci_dev->dev; int ret; /* Use of_reserved_mem_device_init_by_idx() if reserved memory is * attached to platform device of_node. */ ret = of_reserved_mem_device_init(dev_pci); if (ret) cnss_pr_err("Failed to init reserved mem device, err = %d\n", ret); if (dev_pci->cma_area) cnss_pr_dbg("CMA area is %s\n", cma_get_name(dev_pci->cma_area)); return ret; } #else static int cnss_pci_of_reserved_mem_device_init(struct cnss_pci_data *pci_priv) { return 0; } #endif /* 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 Loading Loading @@ -5097,12 +5279,7 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, if (plat_priv->use_pm_domain) dev->pm_domain = &cnss_pm_domain; ret = of_reserved_mem_device_init(dev); if (ret) cnss_pr_err("Failed to init reserved mem device, err = %d\n", ret); if (dev->cma_area) cnss_pr_dbg("CMA area is %s\n", cma_get_name(dev->cma_area)); cnss_pci_of_reserved_mem_device_init(pci_priv); ret = cnss_register_subsys(plat_priv); if (ret) Loading Loading @@ -5151,6 +5328,7 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, cnss_pci_time_sync_work_hdlr); cnss_pci_get_link_status(pci_priv); cnss_pci_set_wlaon_pwr_ctrl(pci_priv, false, true, false); cnss_pci_wake_gpio_init(pci_priv); break; default: cnss_pr_err("Unknown PCI device found: 0x%x\n", Loading Loading @@ -5204,6 +5382,7 @@ static void cnss_pci_remove(struct pci_dev *pci_dev) case QCA6390_DEVICE_ID: case QCA6490_DEVICE_ID: case WCN7850_DEVICE_ID: cnss_pci_wake_gpio_deinit(pci_priv); complete_all(&pci_priv->wake_event); del_timer(&pci_priv->dev_rddm_timer); break; Loading @@ -5223,7 +5402,6 @@ static void cnss_pci_remove(struct pci_dev *pci_dev) } else { cnss_pr_err("Plat_priv is null, Unable to unregister ramdump,subsys\n"); } } static const struct pci_device_id cnss_pci_id_table[] = { Loading