Loading drivers/net/wireless/cnss2/main.c +103 −48 Original line number Diff line number Diff line Loading @@ -2230,75 +2230,130 @@ int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv, return ret; } /** * cnss_register_bus_scale() - Setup interconnect voting data * @plat_priv: Platform data structure * * For different interconnect path configured in device tree setup voting data * for list of bandwidth requirements. * * Result: 0 for success. -EINVAL if not configured */ static int cnss_register_bus_scale(struct cnss_plat_data *plat_priv) { int ret = 0, len = 0, i, j; struct cnss_bus_bw_info *bus_bw_info; const u32 *cfg_arr; bus_bw_info = &plat_priv->bus_bw_info; bus_bw_info->cnss_path = of_icc_get(&plat_priv->plat_dev->dev, NULL); if (!bus_bw_info->cnss_path) { cnss_pr_err("Skip Bus BW setup. Interconnect not configured\n"); return 0; } int ret = -EINVAL; u32 idx, i, j, cfg_arr_size, *cfg_arr; struct cnss_bus_bw_info *bus_bw_info, *tmp; struct device *dev = &plat_priv->plat_dev->dev; if (IS_ERR(bus_bw_info->cnss_path)) { ret = PTR_ERR(bus_bw_info->cnss_path); if (ret != -EPROBE_DEFER) { cnss_pr_err("Failed to get Interconnect path: %d!\n", ret); goto out; } INIT_LIST_HEAD(&plat_priv->icc.list_head); ret = of_property_read_u32(dev->of_node, "qcom,icc-path-count", &plat_priv->icc.path_count); if (ret) { cnss_pr_err("Platform Bus Interconnect path not configured\n"); return -EINVAL; } ret = of_property_read_u32(plat_priv->plat_dev->dev.of_node, "qcom,bus-bw-cfg-num", &bus_bw_info->num_cfg); "qcom,bus-bw-cfg-count", &plat_priv->icc.bus_bw_cfg_count); if (ret) { cnss_pr_err("Failed to get Bus BW Config table size\n"); goto cleanup; } cfg_arr_size = plat_priv->icc.path_count * plat_priv->icc.bus_bw_cfg_count * CNSS_ICC_VOTE_MAX; cfg_arr = kzalloc(cfg_arr_size, GFP_KERNEL); if (!cfg_arr) { cnss_pr_err("Failed to alloc cfg table mem\n"); ret = -ENOMEM; goto cleanup; } ret = of_property_read_u32_array(plat_priv->plat_dev->dev.of_node, "qcom,bus-bw-cfg", cfg_arr, cfg_arr_size); if (ret) { cnss_pr_err("Invalid Bus BW Config Table\n"); goto cleanup; } cnss_pr_dbg("ICC Path_Count: %d BW_CFG_Count: %d\n", plat_priv->icc.path_count, plat_priv->icc.bus_bw_cfg_count); for (idx = 0; idx < plat_priv->icc.path_count; idx++) { bus_bw_info = devm_kzalloc(dev, sizeof(*bus_bw_info), GFP_KERNEL); if (!bus_bw_info) { ret = -ENOMEM; goto out; } ret = of_property_read_string_index(dev->of_node, "interconnect-names", idx, &bus_bw_info->icc_name); if (ret) goto out; cfg_arr = of_get_property(plat_priv->plat_dev->dev.of_node, "qcom,bus-bw-cfg", &len); if (!cfg_arr) { cnss_pr_err("Bus BW Config Table not setup!\n"); ret = -EINVAL; bus_bw_info->icc_path = of_icc_get(&plat_priv->plat_dev->dev, bus_bw_info->icc_name); if (IS_ERR(bus_bw_info->icc_path)) { ret = PTR_ERR(bus_bw_info->icc_path); if (ret != -EPROBE_DEFER) { cnss_pr_err("Failed to get Interconnect path for %s. Err: %d\n", bus_bw_info->icc_name, ret); goto out; } } bus_bw_info->cfg_table = kcalloc(bus_bw_info->num_cfg, bus_bw_info->cfg_table = devm_kcalloc(dev, plat_priv->icc.bus_bw_cfg_count, sizeof(*bus_bw_info->cfg_table), GFP_KERNEL); if (!bus_bw_info->cfg_table) { cnss_pr_err("No mem for Bus BW config table\n"); return -ENOMEM; } for (i = 0, j = 0; i < bus_bw_info->num_cfg; i++, j += 2) { bus_bw_info->cfg_table[i].ab = be32_to_cpu(cfg_arr[j]); bus_bw_info->cfg_table[i].ib = be32_to_cpu(cfg_arr[j + 1]); cnss_pr_dbg("Bandwidth Type: %d bw_cfg.ab: %d bw_cfg.ib: %d\n", i, bus_bw_info->cfg_table[i].ab, bus_bw_info->cfg_table[i].ib); ret = -ENOMEM; goto out; } cnss_pr_dbg("ICC Vote CFG for path: %s\n", bus_bw_info->icc_name); for (i = 0, j = (idx * plat_priv->icc.bus_bw_cfg_count * CNSS_ICC_VOTE_MAX); i < plat_priv->icc.bus_bw_cfg_count; i++, j += 2) { bus_bw_info->cfg_table[i].avg_bw = cfg_arr[j]; bus_bw_info->cfg_table[i].peak_bw = cfg_arr[j + 1]; cnss_pr_dbg("ICC Vote BW: %d avg: %d peak: %d\n", i, bus_bw_info->cfg_table[i].avg_bw, bus_bw_info->cfg_table[i].peak_bw); } list_add_tail(&bus_bw_info->list, &plat_priv->icc.list_head); } kfree(cfg_arr); return 0; out: list_for_each_entry_safe(bus_bw_info, tmp, &plat_priv->icc.list_head, list) { list_del(&bus_bw_info->list); } cleanup: kfree(cfg_arr); memset(&plat_priv->icc, 0, sizeof(plat_priv->icc)); return ret; } static void cnss_unregister_bus_scale(struct cnss_plat_data *plat_priv) { struct cnss_bus_bw_info *bus_bw_info; bus_bw_info = &plat_priv->bus_bw_info; struct cnss_bus_bw_info *bus_bw_info, *tmp; if (bus_bw_info->cnss_path) icc_put(bus_bw_info->cnss_path); kfree(bus_bw_info->cfg_table); list_for_each_entry_safe(bus_bw_info, tmp, &plat_priv->icc.list_head, list) { list_del(&bus_bw_info->list); if (bus_bw_info->icc_path) icc_put(bus_bw_info->icc_path); } memset(&plat_priv->icc, 0, sizeof(plat_priv->icc)); } static ssize_t recovery_store(struct device *dev, Loading drivers/net/wireless/cnss2/main.h +36 −6 Original line number Diff line number Diff line Loading @@ -140,18 +140,48 @@ struct cnss_esoc_info { }; #endif /** * struct cnss_bus_bw_cfg - Interconnect vote data * @avg_bw: Vote for average bandwidth * @peak_bw: Vote for peak bandwidth */ struct cnss_bus_bw_cfg { u32 ab; u32 ib; u32 avg_bw; u32 peak_bw; }; /* Number of bw votes (avg, peak) entries that ICC requires */ #define CNSS_ICC_VOTE_MAX 2 /** * struct cnss_bus_bw_info - Bus bandwidth config for interconnect path * @list: Kernel linked list * @icc_name: Name of interconnect path as defined in Device tree * @icc_path: Interconnect path data structure * @cfg_table: Interconnect vote data for average and peak bandwidth */ struct cnss_bus_bw_info { struct icc_path *cnss_path; int current_bw_vote; u32 num_cfg; struct list_head list; const char *icc_name; struct icc_path *icc_path; struct cnss_bus_bw_cfg *cfg_table; }; /** * struct cnss_interconnect_cfg - CNSS platform interconnect config * @list_head: List of interconnect path bandwidth configs * @path_count: Count of interconnect path configured in device tree * @current_bw_vote: WLAN driver provided bandwidth vote * @bus_bw_cfg_count: Number of bandwidth configs for voting. It is the array * size of struct cnss_bus_bw_info.cfg_table */ struct cnss_interconnect_cfg { struct list_head list_head; u32 path_count; int current_bw_vote; u32 bus_bw_cfg_count; }; struct cnss_fw_mem { size_t size; void *va; Loading Loading @@ -360,7 +390,7 @@ struct cnss_plat_data { #if IS_ENABLED(CONFIG_ESOC) struct cnss_esoc_info esoc_info; #endif struct cnss_bus_bw_info bus_bw_info; struct cnss_interconnect_cfg icc; struct notifier_block modem_nb; struct notifier_block reboot_nb; struct notifier_block panic_nb; Loading drivers/net/wireless/cnss2/pci.c +45 −37 Original line number Diff line number Diff line Loading @@ -509,43 +509,59 @@ static int cnss_pci_force_wake_put(struct cnss_pci_data *pci_priv) return ret; } int cnss_request_bus_bandwidth(struct device *dev, int bandwidth) /** * cnss_setup_bus_bandwidth() - Setup interconnect vote for given bandwidth * @plat_priv: Platform private data struct * @bw: bandwidth * @save: toggle flag to save bandwidth to current_bw_vote * * Setup bandwidth votes for configured interconnect paths * * Return: 0 for success */ static int cnss_setup_bus_bandwidth(struct cnss_plat_data *plat_priv, u32 bw, bool save) { int ret = 0; struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); struct cnss_bus_bw_info *bus_bw_info; if (!plat_priv) return -ENODEV; if (!plat_priv->icc.path_count) return -ENOTSUPP; bus_bw_info = &plat_priv->bus_bw_info; if (!bus_bw_info->cnss_path || bandwidth > bus_bw_info->num_cfg) if (bw >= plat_priv->icc.bus_bw_cfg_count) { cnss_pr_err("Invalid bus bandwidth Type: %d", bw); return -EINVAL; } switch (bandwidth) { case CNSS_BUS_WIDTH_NONE: case CNSS_BUS_WIDTH_IDLE: case CNSS_BUS_WIDTH_LOW: case CNSS_BUS_WIDTH_MEDIUM: case CNSS_BUS_WIDTH_HIGH: case CNSS_BUS_WIDTH_VERY_HIGH: case CNSS_BUS_WIDTH_LOW_LATENCY: ret = icc_set_bw(bus_bw_info->cnss_path, bus_bw_info->cfg_table[bandwidth].ab, bus_bw_info->cfg_table[bandwidth].ib); if (!ret) bus_bw_info->current_bw_vote = bandwidth; else cnss_pr_err("Could not set bus bandwidth: %d, err = %d\n", bandwidth, ret); list_for_each_entry(bus_bw_info, &plat_priv->icc.list_head, list) { ret = icc_set_bw(bus_bw_info->icc_path, bus_bw_info->cfg_table[bw].avg_bw, bus_bw_info->cfg_table[bw].peak_bw); if (ret) { cnss_pr_err("Could not set BW Cfg: %d, err = %d ICC Path: %s Val: %d %d\n", bw, ret, bus_bw_info->icc_name, bus_bw_info->cfg_table[bw].avg_bw, bus_bw_info->cfg_table[bw].peak_bw); break; default: cnss_pr_err("Invalid bus bandwidth: %d", bandwidth); ret = -EINVAL; } } if (ret == 0 && save) plat_priv->icc.current_bw_vote = bw; return ret; } int cnss_request_bus_bandwidth(struct device *dev, int bandwidth) { struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); if (!plat_priv) return -ENODEV; if (bandwidth < 0) return -EINVAL; return cnss_setup_bus_bandwidth(plat_priv, (u32)bandwidth, true); } EXPORT_SYMBOL(cnss_request_bus_bandwidth); int cnss_pci_debug_reg_read(struct cnss_pci_data *pci_priv, u32 offset, Loading Loading @@ -2987,7 +3003,6 @@ int cnss_auto_suspend(struct device *dev) 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_bus_bw_info *bus_bw_info; if (!pci_priv) return -ENODEV; Loading @@ -3008,18 +3023,11 @@ int cnss_auto_suspend(struct device *dev) cnss_pci_set_monitor_wake_intr(pci_priv, true); bus_bw_info = &plat_priv->bus_bw_info; if (!bus_bw_info->cnss_path) goto out; /* For suspend temporarily set bandwidth vote to NONE and dont save in * current_bw_vote as in resume path we should vote for last used * bandwidth vote. Also ignore error if bw voting is not setup. */ icc_set_bw(bus_bw_info->cnss_path, bus_bw_info->cfg_table[CNSS_BUS_WIDTH_NONE].ab, bus_bw_info->cfg_table[CNSS_BUS_WIDTH_NONE].ib); out: cnss_setup_bus_bandwidth(plat_priv, CNSS_BUS_WIDTH_NONE, false); return 0; } EXPORT_SYMBOL(cnss_auto_suspend); Loading Loading @@ -3048,7 +3056,7 @@ int cnss_auto_resume(struct device *dev) cnss_pci_set_auto_suspended(pci_priv, 0); mutex_unlock(&pci_priv->bus_lock); cnss_request_bus_bandwidth(dev, plat_priv->bus_bw_info.current_bw_vote); cnss_request_bus_bandwidth(dev, plat_priv->icc.current_bw_vote); return 0; } Loading Loading
drivers/net/wireless/cnss2/main.c +103 −48 Original line number Diff line number Diff line Loading @@ -2230,75 +2230,130 @@ int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv, return ret; } /** * cnss_register_bus_scale() - Setup interconnect voting data * @plat_priv: Platform data structure * * For different interconnect path configured in device tree setup voting data * for list of bandwidth requirements. * * Result: 0 for success. -EINVAL if not configured */ static int cnss_register_bus_scale(struct cnss_plat_data *plat_priv) { int ret = 0, len = 0, i, j; struct cnss_bus_bw_info *bus_bw_info; const u32 *cfg_arr; bus_bw_info = &plat_priv->bus_bw_info; bus_bw_info->cnss_path = of_icc_get(&plat_priv->plat_dev->dev, NULL); if (!bus_bw_info->cnss_path) { cnss_pr_err("Skip Bus BW setup. Interconnect not configured\n"); return 0; } int ret = -EINVAL; u32 idx, i, j, cfg_arr_size, *cfg_arr; struct cnss_bus_bw_info *bus_bw_info, *tmp; struct device *dev = &plat_priv->plat_dev->dev; if (IS_ERR(bus_bw_info->cnss_path)) { ret = PTR_ERR(bus_bw_info->cnss_path); if (ret != -EPROBE_DEFER) { cnss_pr_err("Failed to get Interconnect path: %d!\n", ret); goto out; } INIT_LIST_HEAD(&plat_priv->icc.list_head); ret = of_property_read_u32(dev->of_node, "qcom,icc-path-count", &plat_priv->icc.path_count); if (ret) { cnss_pr_err("Platform Bus Interconnect path not configured\n"); return -EINVAL; } ret = of_property_read_u32(plat_priv->plat_dev->dev.of_node, "qcom,bus-bw-cfg-num", &bus_bw_info->num_cfg); "qcom,bus-bw-cfg-count", &plat_priv->icc.bus_bw_cfg_count); if (ret) { cnss_pr_err("Failed to get Bus BW Config table size\n"); goto cleanup; } cfg_arr_size = plat_priv->icc.path_count * plat_priv->icc.bus_bw_cfg_count * CNSS_ICC_VOTE_MAX; cfg_arr = kzalloc(cfg_arr_size, GFP_KERNEL); if (!cfg_arr) { cnss_pr_err("Failed to alloc cfg table mem\n"); ret = -ENOMEM; goto cleanup; } ret = of_property_read_u32_array(plat_priv->plat_dev->dev.of_node, "qcom,bus-bw-cfg", cfg_arr, cfg_arr_size); if (ret) { cnss_pr_err("Invalid Bus BW Config Table\n"); goto cleanup; } cnss_pr_dbg("ICC Path_Count: %d BW_CFG_Count: %d\n", plat_priv->icc.path_count, plat_priv->icc.bus_bw_cfg_count); for (idx = 0; idx < plat_priv->icc.path_count; idx++) { bus_bw_info = devm_kzalloc(dev, sizeof(*bus_bw_info), GFP_KERNEL); if (!bus_bw_info) { ret = -ENOMEM; goto out; } ret = of_property_read_string_index(dev->of_node, "interconnect-names", idx, &bus_bw_info->icc_name); if (ret) goto out; cfg_arr = of_get_property(plat_priv->plat_dev->dev.of_node, "qcom,bus-bw-cfg", &len); if (!cfg_arr) { cnss_pr_err("Bus BW Config Table not setup!\n"); ret = -EINVAL; bus_bw_info->icc_path = of_icc_get(&plat_priv->plat_dev->dev, bus_bw_info->icc_name); if (IS_ERR(bus_bw_info->icc_path)) { ret = PTR_ERR(bus_bw_info->icc_path); if (ret != -EPROBE_DEFER) { cnss_pr_err("Failed to get Interconnect path for %s. Err: %d\n", bus_bw_info->icc_name, ret); goto out; } } bus_bw_info->cfg_table = kcalloc(bus_bw_info->num_cfg, bus_bw_info->cfg_table = devm_kcalloc(dev, plat_priv->icc.bus_bw_cfg_count, sizeof(*bus_bw_info->cfg_table), GFP_KERNEL); if (!bus_bw_info->cfg_table) { cnss_pr_err("No mem for Bus BW config table\n"); return -ENOMEM; } for (i = 0, j = 0; i < bus_bw_info->num_cfg; i++, j += 2) { bus_bw_info->cfg_table[i].ab = be32_to_cpu(cfg_arr[j]); bus_bw_info->cfg_table[i].ib = be32_to_cpu(cfg_arr[j + 1]); cnss_pr_dbg("Bandwidth Type: %d bw_cfg.ab: %d bw_cfg.ib: %d\n", i, bus_bw_info->cfg_table[i].ab, bus_bw_info->cfg_table[i].ib); ret = -ENOMEM; goto out; } cnss_pr_dbg("ICC Vote CFG for path: %s\n", bus_bw_info->icc_name); for (i = 0, j = (idx * plat_priv->icc.bus_bw_cfg_count * CNSS_ICC_VOTE_MAX); i < plat_priv->icc.bus_bw_cfg_count; i++, j += 2) { bus_bw_info->cfg_table[i].avg_bw = cfg_arr[j]; bus_bw_info->cfg_table[i].peak_bw = cfg_arr[j + 1]; cnss_pr_dbg("ICC Vote BW: %d avg: %d peak: %d\n", i, bus_bw_info->cfg_table[i].avg_bw, bus_bw_info->cfg_table[i].peak_bw); } list_add_tail(&bus_bw_info->list, &plat_priv->icc.list_head); } kfree(cfg_arr); return 0; out: list_for_each_entry_safe(bus_bw_info, tmp, &plat_priv->icc.list_head, list) { list_del(&bus_bw_info->list); } cleanup: kfree(cfg_arr); memset(&plat_priv->icc, 0, sizeof(plat_priv->icc)); return ret; } static void cnss_unregister_bus_scale(struct cnss_plat_data *plat_priv) { struct cnss_bus_bw_info *bus_bw_info; bus_bw_info = &plat_priv->bus_bw_info; struct cnss_bus_bw_info *bus_bw_info, *tmp; if (bus_bw_info->cnss_path) icc_put(bus_bw_info->cnss_path); kfree(bus_bw_info->cfg_table); list_for_each_entry_safe(bus_bw_info, tmp, &plat_priv->icc.list_head, list) { list_del(&bus_bw_info->list); if (bus_bw_info->icc_path) icc_put(bus_bw_info->icc_path); } memset(&plat_priv->icc, 0, sizeof(plat_priv->icc)); } static ssize_t recovery_store(struct device *dev, Loading
drivers/net/wireless/cnss2/main.h +36 −6 Original line number Diff line number Diff line Loading @@ -140,18 +140,48 @@ struct cnss_esoc_info { }; #endif /** * struct cnss_bus_bw_cfg - Interconnect vote data * @avg_bw: Vote for average bandwidth * @peak_bw: Vote for peak bandwidth */ struct cnss_bus_bw_cfg { u32 ab; u32 ib; u32 avg_bw; u32 peak_bw; }; /* Number of bw votes (avg, peak) entries that ICC requires */ #define CNSS_ICC_VOTE_MAX 2 /** * struct cnss_bus_bw_info - Bus bandwidth config for interconnect path * @list: Kernel linked list * @icc_name: Name of interconnect path as defined in Device tree * @icc_path: Interconnect path data structure * @cfg_table: Interconnect vote data for average and peak bandwidth */ struct cnss_bus_bw_info { struct icc_path *cnss_path; int current_bw_vote; u32 num_cfg; struct list_head list; const char *icc_name; struct icc_path *icc_path; struct cnss_bus_bw_cfg *cfg_table; }; /** * struct cnss_interconnect_cfg - CNSS platform interconnect config * @list_head: List of interconnect path bandwidth configs * @path_count: Count of interconnect path configured in device tree * @current_bw_vote: WLAN driver provided bandwidth vote * @bus_bw_cfg_count: Number of bandwidth configs for voting. It is the array * size of struct cnss_bus_bw_info.cfg_table */ struct cnss_interconnect_cfg { struct list_head list_head; u32 path_count; int current_bw_vote; u32 bus_bw_cfg_count; }; struct cnss_fw_mem { size_t size; void *va; Loading Loading @@ -360,7 +390,7 @@ struct cnss_plat_data { #if IS_ENABLED(CONFIG_ESOC) struct cnss_esoc_info esoc_info; #endif struct cnss_bus_bw_info bus_bw_info; struct cnss_interconnect_cfg icc; struct notifier_block modem_nb; struct notifier_block reboot_nb; struct notifier_block panic_nb; Loading
drivers/net/wireless/cnss2/pci.c +45 −37 Original line number Diff line number Diff line Loading @@ -509,43 +509,59 @@ static int cnss_pci_force_wake_put(struct cnss_pci_data *pci_priv) return ret; } int cnss_request_bus_bandwidth(struct device *dev, int bandwidth) /** * cnss_setup_bus_bandwidth() - Setup interconnect vote for given bandwidth * @plat_priv: Platform private data struct * @bw: bandwidth * @save: toggle flag to save bandwidth to current_bw_vote * * Setup bandwidth votes for configured interconnect paths * * Return: 0 for success */ static int cnss_setup_bus_bandwidth(struct cnss_plat_data *plat_priv, u32 bw, bool save) { int ret = 0; struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); struct cnss_bus_bw_info *bus_bw_info; if (!plat_priv) return -ENODEV; if (!plat_priv->icc.path_count) return -ENOTSUPP; bus_bw_info = &plat_priv->bus_bw_info; if (!bus_bw_info->cnss_path || bandwidth > bus_bw_info->num_cfg) if (bw >= plat_priv->icc.bus_bw_cfg_count) { cnss_pr_err("Invalid bus bandwidth Type: %d", bw); return -EINVAL; } switch (bandwidth) { case CNSS_BUS_WIDTH_NONE: case CNSS_BUS_WIDTH_IDLE: case CNSS_BUS_WIDTH_LOW: case CNSS_BUS_WIDTH_MEDIUM: case CNSS_BUS_WIDTH_HIGH: case CNSS_BUS_WIDTH_VERY_HIGH: case CNSS_BUS_WIDTH_LOW_LATENCY: ret = icc_set_bw(bus_bw_info->cnss_path, bus_bw_info->cfg_table[bandwidth].ab, bus_bw_info->cfg_table[bandwidth].ib); if (!ret) bus_bw_info->current_bw_vote = bandwidth; else cnss_pr_err("Could not set bus bandwidth: %d, err = %d\n", bandwidth, ret); list_for_each_entry(bus_bw_info, &plat_priv->icc.list_head, list) { ret = icc_set_bw(bus_bw_info->icc_path, bus_bw_info->cfg_table[bw].avg_bw, bus_bw_info->cfg_table[bw].peak_bw); if (ret) { cnss_pr_err("Could not set BW Cfg: %d, err = %d ICC Path: %s Val: %d %d\n", bw, ret, bus_bw_info->icc_name, bus_bw_info->cfg_table[bw].avg_bw, bus_bw_info->cfg_table[bw].peak_bw); break; default: cnss_pr_err("Invalid bus bandwidth: %d", bandwidth); ret = -EINVAL; } } if (ret == 0 && save) plat_priv->icc.current_bw_vote = bw; return ret; } int cnss_request_bus_bandwidth(struct device *dev, int bandwidth) { struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); if (!plat_priv) return -ENODEV; if (bandwidth < 0) return -EINVAL; return cnss_setup_bus_bandwidth(plat_priv, (u32)bandwidth, true); } EXPORT_SYMBOL(cnss_request_bus_bandwidth); int cnss_pci_debug_reg_read(struct cnss_pci_data *pci_priv, u32 offset, Loading Loading @@ -2987,7 +3003,6 @@ int cnss_auto_suspend(struct device *dev) 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_bus_bw_info *bus_bw_info; if (!pci_priv) return -ENODEV; Loading @@ -3008,18 +3023,11 @@ int cnss_auto_suspend(struct device *dev) cnss_pci_set_monitor_wake_intr(pci_priv, true); bus_bw_info = &plat_priv->bus_bw_info; if (!bus_bw_info->cnss_path) goto out; /* For suspend temporarily set bandwidth vote to NONE and dont save in * current_bw_vote as in resume path we should vote for last used * bandwidth vote. Also ignore error if bw voting is not setup. */ icc_set_bw(bus_bw_info->cnss_path, bus_bw_info->cfg_table[CNSS_BUS_WIDTH_NONE].ab, bus_bw_info->cfg_table[CNSS_BUS_WIDTH_NONE].ib); out: cnss_setup_bus_bandwidth(plat_priv, CNSS_BUS_WIDTH_NONE, false); return 0; } EXPORT_SYMBOL(cnss_auto_suspend); Loading Loading @@ -3048,7 +3056,7 @@ int cnss_auto_resume(struct device *dev) cnss_pci_set_auto_suspended(pci_priv, 0); mutex_unlock(&pci_priv->bus_lock); cnss_request_bus_bandwidth(dev, plat_priv->bus_bw_info.current_bw_vote); cnss_request_bus_bandwidth(dev, plat_priv->icc.current_bw_vote); return 0; } Loading