Loading drivers/soc/qcom/icnss.c +158 −4 Original line number Original line Diff line number Diff line Loading @@ -79,6 +79,40 @@ void *icnss_ipc_log_long_context; #define ICNSS_EVENT_UNINTERRUPTIBLE BIT(1) #define ICNSS_EVENT_UNINTERRUPTIBLE BIT(1) #define ICNSS_EVENT_SYNC_UNINTERRUPTIBLE (ICNSS_EVENT_UNINTERRUPTIBLE | \ #define ICNSS_EVENT_SYNC_UNINTERRUPTIBLE (ICNSS_EVENT_UNINTERRUPTIBLE | \ ICNSS_EVENT_SYNC) ICNSS_EVENT_SYNC) struct icnss_msa_perm_list_t msa_perm_secure_list[ICNSS_MSA_PERM_MAX] = { [ICNSS_MSA_PERM_HLOS_ALL] = { .vmids = {VMID_HLOS}, .perms = {PERM_READ | PERM_WRITE | PERM_EXEC}, .nelems = 1, }, [ICNSS_MSA_PERM_WLAN_HW_RW] = { .vmids = {VMID_MSS_MSA, VMID_WLAN}, .perms = {PERM_READ | PERM_WRITE, PERM_READ | PERM_WRITE}, .nelems = 2, }, }; struct icnss_msa_perm_list_t msa_perm_list[ICNSS_MSA_PERM_MAX] = { [ICNSS_MSA_PERM_HLOS_ALL] = { .vmids = {VMID_HLOS}, .perms = {PERM_READ | PERM_WRITE | PERM_EXEC}, .nelems = 1, }, [ICNSS_MSA_PERM_WLAN_HW_RW] = { .vmids = {VMID_MSS_MSA, VMID_WLAN, VMID_WLAN_CE}, .perms = {PERM_READ | PERM_WRITE, PERM_READ | PERM_WRITE, PERM_READ | PERM_WRITE}, .nelems = 3, }, }; static struct icnss_vreg_info icnss_vreg_info[] = { static struct icnss_vreg_info icnss_vreg_info[] = { {NULL, "vdd-cx-mx", 752000, 752000, 0, 0, false}, {NULL, "vdd-cx-mx", 752000, 752000, 0, 0, false}, {NULL, "vdd-1.8-xo", 1800000, 1800000, 0, 0, false}, {NULL, "vdd-1.8-xo", 1800000, 1800000, 0, 0, false}, Loading Loading @@ -121,6 +155,94 @@ static ssize_t icnss_sysfs_store(struct kobject *kobj, static struct kobj_attribute icnss_sysfs_attribute = static struct kobj_attribute icnss_sysfs_attribute = __ATTR(shutdown, 0660, NULL, icnss_sysfs_store); __ATTR(shutdown, 0660, NULL, icnss_sysfs_store); static int icnss_assign_msa_perm(struct icnss_mem_region_info *mem_region, enum icnss_msa_perm new_perm) { int ret = 0; phys_addr_t addr; u32 size; u32 i = 0; u32 source_vmids[ICNSS_MAX_VMIDS] = {0}; u32 source_nelems; u32 dest_vmids[ICNSS_MAX_VMIDS] = {0}; u32 dest_perms[ICNSS_MAX_VMIDS] = {0}; u32 dest_nelems; enum icnss_msa_perm cur_perm = mem_region->perm; struct icnss_msa_perm_list_t *new_perm_list, *old_perm_list; if (penv && !penv->is_hyp_enabled) { icnss_pr_err("hyperviser disabled"); return 0; } addr = mem_region->reg_addr; size = mem_region->size; if (mem_region->secure_flag) { new_perm_list = &msa_perm_secure_list[new_perm]; old_perm_list = &msa_perm_secure_list[cur_perm]; } else { new_perm_list = &msa_perm_list[new_perm]; old_perm_list = &msa_perm_list[cur_perm]; } source_nelems = old_perm_list->nelems; dest_nelems = new_perm_list->nelems; for (i = 0; i < source_nelems; ++i) source_vmids[i] = old_perm_list->vmids[i]; for (i = 0; i < dest_nelems; ++i) { dest_vmids[i] = new_perm_list->vmids[i]; dest_perms[i] = new_perm_list->perms[i]; } ret = hyp_assign_phys(addr, size, source_vmids, source_nelems, dest_vmids, dest_perms, dest_nelems); if (ret) { icnss_pr_err("Hyperviser map failed for PA=%pa size=%u err=%d\n", &addr, size, ret); goto out; } icnss_pr_dbg("Hypervisor map for source_nelems=%d, source[0]=%x, source[1]=%x, source[2]=%x, source[3]=%x, dest_nelems=%d, dest[0]=%x, dest[1]=%x, dest[2]=%x, dest[3]=%x\n", source_nelems, source_vmids[0], source_vmids[1], source_vmids[2], source_vmids[3], dest_nelems, dest_vmids[0], dest_vmids[1], dest_vmids[2], dest_vmids[3]); out: return ret; } static int icnss_assign_msa_perm_all(struct icnss_priv *priv, enum icnss_msa_perm new_perm) { int ret; int i; enum icnss_msa_perm old_perm; if (priv->nr_mem_region > WLFW_MAX_NUM_MEMORY_REGIONS) { icnss_pr_err("Invalid memory region len %d\n", priv->nr_mem_region); return -EINVAL; } for (i = 0; i < priv->nr_mem_region; i++) { old_perm = priv->mem_region[i].perm; ret = icnss_assign_msa_perm(&priv->mem_region[i], new_perm); if (ret) goto err_unmap; priv->mem_region[i].perm = new_perm; } return 0; err_unmap: for (i--; i >= 0; i--) icnss_assign_msa_perm(&priv->mem_region[i], old_perm); return ret; } static void icnss_pm_stay_awake(struct icnss_priv *priv) static void icnss_pm_stay_awake(struct icnss_priv *priv) { { if (atomic_inc_return(&priv->pm_count) != 1) if (atomic_inc_return(&priv->pm_count) != 1) Loading Loading @@ -885,16 +1007,24 @@ static int icnss_driver_event_server_arrive(void *data) goto err_power_on; goto err_power_on; } } if (!test_bit(ICNSS_MSA0_ASSIGNED, &penv->state)) { ret = icnss_assign_msa_perm_all(penv, ICNSS_MSA_PERM_WLAN_HW_RW); if (ret < 0) goto err_power_on; set_bit(ICNSS_MSA0_ASSIGNED, &penv->state); } ret = wlfw_msa_ready_send_sync_msg(penv); ret = wlfw_msa_ready_send_sync_msg(penv); if (ret < 0) { if (ret < 0) { ignore_assert = true; ignore_assert = true; goto err_power_on; goto err_setup_msa; } } ret = wlfw_cap_send_sync_msg(penv); ret = wlfw_cap_send_sync_msg(penv); if (ret < 0) { if (ret < 0) { ignore_assert = true; ignore_assert = true; goto err_power_on; goto err_setup_msa; } } wlfw_dynamic_feature_mask_send_sync_msg(penv, wlfw_dynamic_feature_mask_send_sync_msg(penv, Loading @@ -911,6 +1041,9 @@ static int icnss_driver_event_server_arrive(void *data) return ret; return ret; err_setup_msa: icnss_assign_msa_perm_all(penv, ICNSS_MSA_PERM_HLOS_ALL); clear_bit(ICNSS_MSA0_ASSIGNED, &penv->state); err_power_on: err_power_on: icnss_hw_power_off(penv); icnss_hw_power_off(penv); clear_server: clear_server: Loading Loading @@ -1455,13 +1588,23 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, struct icnss_priv *priv = container_of(nb, struct icnss_priv, struct icnss_priv *priv = container_of(nb, struct icnss_priv, modem_ssr_nb); modem_ssr_nb); struct icnss_uevent_fw_down_data fw_down_data = {0}; struct icnss_uevent_fw_down_data fw_down_data = {0}; int ret; icnss_pr_vdbg("Modem-Notify: event %lu\n", code); icnss_pr_vdbg("Modem-Notify: event %lu\n", code); if (code == SUBSYS_AFTER_SHUTDOWN && if (code == SUBSYS_AFTER_SHUTDOWN && notif->crashed == CRASH_STATUS_ERR_FATAL) { notif->crashed == CRASH_STATUS_ERR_FATAL) { ret = icnss_assign_msa_perm_all(priv, ICNSS_MSA_PERM_HLOS_ALL); if (!ret) { icnss_pr_info("Collecting msa0 segment dump\n"); icnss_pr_info("Collecting msa0 segment dump\n"); icnss_msa0_ramdump(priv); icnss_msa0_ramdump(priv); icnss_assign_msa_perm_all(priv, ICNSS_MSA_PERM_WLAN_HW_RW); } else { icnss_pr_err("Not able to Collect msa0 segment dump, Apps permissions not assigned %d\n", ret); } goto out; goto out; } } Loading Loading @@ -2777,6 +2920,9 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv) case ICNSS_PD_RESTART: case ICNSS_PD_RESTART: seq_puts(s, "PD RESTART"); seq_puts(s, "PD RESTART"); continue; continue; case ICNSS_MSA0_ASSIGNED: seq_puts(s, "MSA0 ASSIGNED"); continue; case ICNSS_WLFW_EXISTS: case ICNSS_WLFW_EXISTS: seq_puts(s, "WLAN FW EXISTS"); seq_puts(s, "WLAN FW EXISTS"); continue; continue; Loading Loading @@ -3344,6 +3490,11 @@ static int icnss_resource_parse(struct icnss_priv *priv) goto out; goto out; } } if (of_property_read_bool(pdev->dev.of_node, "qcom,hyp_enabled")) priv->is_hyp_enabled = true; icnss_pr_dbg("Hypervisor enabled = %d\n", priv->is_hyp_enabled); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "membase"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "membase"); if (!res) { if (!res) { icnss_pr_err("Memory base not found in DT\n"); icnss_pr_err("Memory base not found in DT\n"); Loading Loading @@ -3593,6 +3744,9 @@ static int icnss_remove(struct platform_device *pdev) icnss_hw_power_off(penv); icnss_hw_power_off(penv); icnss_assign_msa_perm_all(penv, ICNSS_MSA_PERM_HLOS_ALL); clear_bit(ICNSS_MSA0_ASSIGNED, &penv->state); dev_set_drvdata(&pdev->dev, NULL); dev_set_drvdata(&pdev->dev, NULL); return 0; return 0; Loading drivers/soc/qcom/icnss_private.h +17 −0 Original line number Original line Diff line number Diff line Loading @@ -148,6 +148,7 @@ enum icnss_driver_state { ICNSS_SSR_REGISTERED, ICNSS_SSR_REGISTERED, ICNSS_PDR_REGISTERED, ICNSS_PDR_REGISTERED, ICNSS_PD_RESTART, ICNSS_PD_RESTART, ICNSS_MSA0_ASSIGNED, ICNSS_WLFW_EXISTS, ICNSS_WLFW_EXISTS, ICNSS_SHUTDOWN_DONE, ICNSS_SHUTDOWN_DONE, ICNSS_HOST_TRIGGERED_PDR, ICNSS_HOST_TRIGGERED_PDR, Loading Loading @@ -276,10 +277,25 @@ struct wlfw_fw_version_info { char fw_build_timestamp[WLFW_MAX_TIMESTAMP_LEN + 1]; char fw_build_timestamp[WLFW_MAX_TIMESTAMP_LEN + 1]; }; }; enum icnss_msa_perm { ICNSS_MSA_PERM_HLOS_ALL = 0, ICNSS_MSA_PERM_WLAN_HW_RW = 1, ICNSS_MSA_PERM_MAX, }; #define ICNSS_MAX_VMIDS 4 struct icnss_mem_region_info { struct icnss_mem_region_info { uint64_t reg_addr; uint64_t reg_addr; uint32_t size; uint32_t size; uint8_t secure_flag; uint8_t secure_flag; enum icnss_msa_perm perm; }; struct icnss_msa_perm_list_t { int vmids[ICNSS_MAX_VMIDS]; int perms[ICNSS_MAX_VMIDS]; int nelems; }; }; struct icnss_priv { struct icnss_priv { Loading Loading @@ -356,6 +372,7 @@ struct icnss_priv { void __iomem *hang_event_data_va; void __iomem *hang_event_data_va; uint16_t hang_event_data_len; uint16_t hang_event_data_len; void *hang_event_data; void *hang_event_data; bool is_hyp_enabled; }; }; struct icnss_reg_info { struct icnss_reg_info { Loading Loading
drivers/soc/qcom/icnss.c +158 −4 Original line number Original line Diff line number Diff line Loading @@ -79,6 +79,40 @@ void *icnss_ipc_log_long_context; #define ICNSS_EVENT_UNINTERRUPTIBLE BIT(1) #define ICNSS_EVENT_UNINTERRUPTIBLE BIT(1) #define ICNSS_EVENT_SYNC_UNINTERRUPTIBLE (ICNSS_EVENT_UNINTERRUPTIBLE | \ #define ICNSS_EVENT_SYNC_UNINTERRUPTIBLE (ICNSS_EVENT_UNINTERRUPTIBLE | \ ICNSS_EVENT_SYNC) ICNSS_EVENT_SYNC) struct icnss_msa_perm_list_t msa_perm_secure_list[ICNSS_MSA_PERM_MAX] = { [ICNSS_MSA_PERM_HLOS_ALL] = { .vmids = {VMID_HLOS}, .perms = {PERM_READ | PERM_WRITE | PERM_EXEC}, .nelems = 1, }, [ICNSS_MSA_PERM_WLAN_HW_RW] = { .vmids = {VMID_MSS_MSA, VMID_WLAN}, .perms = {PERM_READ | PERM_WRITE, PERM_READ | PERM_WRITE}, .nelems = 2, }, }; struct icnss_msa_perm_list_t msa_perm_list[ICNSS_MSA_PERM_MAX] = { [ICNSS_MSA_PERM_HLOS_ALL] = { .vmids = {VMID_HLOS}, .perms = {PERM_READ | PERM_WRITE | PERM_EXEC}, .nelems = 1, }, [ICNSS_MSA_PERM_WLAN_HW_RW] = { .vmids = {VMID_MSS_MSA, VMID_WLAN, VMID_WLAN_CE}, .perms = {PERM_READ | PERM_WRITE, PERM_READ | PERM_WRITE, PERM_READ | PERM_WRITE}, .nelems = 3, }, }; static struct icnss_vreg_info icnss_vreg_info[] = { static struct icnss_vreg_info icnss_vreg_info[] = { {NULL, "vdd-cx-mx", 752000, 752000, 0, 0, false}, {NULL, "vdd-cx-mx", 752000, 752000, 0, 0, false}, {NULL, "vdd-1.8-xo", 1800000, 1800000, 0, 0, false}, {NULL, "vdd-1.8-xo", 1800000, 1800000, 0, 0, false}, Loading Loading @@ -121,6 +155,94 @@ static ssize_t icnss_sysfs_store(struct kobject *kobj, static struct kobj_attribute icnss_sysfs_attribute = static struct kobj_attribute icnss_sysfs_attribute = __ATTR(shutdown, 0660, NULL, icnss_sysfs_store); __ATTR(shutdown, 0660, NULL, icnss_sysfs_store); static int icnss_assign_msa_perm(struct icnss_mem_region_info *mem_region, enum icnss_msa_perm new_perm) { int ret = 0; phys_addr_t addr; u32 size; u32 i = 0; u32 source_vmids[ICNSS_MAX_VMIDS] = {0}; u32 source_nelems; u32 dest_vmids[ICNSS_MAX_VMIDS] = {0}; u32 dest_perms[ICNSS_MAX_VMIDS] = {0}; u32 dest_nelems; enum icnss_msa_perm cur_perm = mem_region->perm; struct icnss_msa_perm_list_t *new_perm_list, *old_perm_list; if (penv && !penv->is_hyp_enabled) { icnss_pr_err("hyperviser disabled"); return 0; } addr = mem_region->reg_addr; size = mem_region->size; if (mem_region->secure_flag) { new_perm_list = &msa_perm_secure_list[new_perm]; old_perm_list = &msa_perm_secure_list[cur_perm]; } else { new_perm_list = &msa_perm_list[new_perm]; old_perm_list = &msa_perm_list[cur_perm]; } source_nelems = old_perm_list->nelems; dest_nelems = new_perm_list->nelems; for (i = 0; i < source_nelems; ++i) source_vmids[i] = old_perm_list->vmids[i]; for (i = 0; i < dest_nelems; ++i) { dest_vmids[i] = new_perm_list->vmids[i]; dest_perms[i] = new_perm_list->perms[i]; } ret = hyp_assign_phys(addr, size, source_vmids, source_nelems, dest_vmids, dest_perms, dest_nelems); if (ret) { icnss_pr_err("Hyperviser map failed for PA=%pa size=%u err=%d\n", &addr, size, ret); goto out; } icnss_pr_dbg("Hypervisor map for source_nelems=%d, source[0]=%x, source[1]=%x, source[2]=%x, source[3]=%x, dest_nelems=%d, dest[0]=%x, dest[1]=%x, dest[2]=%x, dest[3]=%x\n", source_nelems, source_vmids[0], source_vmids[1], source_vmids[2], source_vmids[3], dest_nelems, dest_vmids[0], dest_vmids[1], dest_vmids[2], dest_vmids[3]); out: return ret; } static int icnss_assign_msa_perm_all(struct icnss_priv *priv, enum icnss_msa_perm new_perm) { int ret; int i; enum icnss_msa_perm old_perm; if (priv->nr_mem_region > WLFW_MAX_NUM_MEMORY_REGIONS) { icnss_pr_err("Invalid memory region len %d\n", priv->nr_mem_region); return -EINVAL; } for (i = 0; i < priv->nr_mem_region; i++) { old_perm = priv->mem_region[i].perm; ret = icnss_assign_msa_perm(&priv->mem_region[i], new_perm); if (ret) goto err_unmap; priv->mem_region[i].perm = new_perm; } return 0; err_unmap: for (i--; i >= 0; i--) icnss_assign_msa_perm(&priv->mem_region[i], old_perm); return ret; } static void icnss_pm_stay_awake(struct icnss_priv *priv) static void icnss_pm_stay_awake(struct icnss_priv *priv) { { if (atomic_inc_return(&priv->pm_count) != 1) if (atomic_inc_return(&priv->pm_count) != 1) Loading Loading @@ -885,16 +1007,24 @@ static int icnss_driver_event_server_arrive(void *data) goto err_power_on; goto err_power_on; } } if (!test_bit(ICNSS_MSA0_ASSIGNED, &penv->state)) { ret = icnss_assign_msa_perm_all(penv, ICNSS_MSA_PERM_WLAN_HW_RW); if (ret < 0) goto err_power_on; set_bit(ICNSS_MSA0_ASSIGNED, &penv->state); } ret = wlfw_msa_ready_send_sync_msg(penv); ret = wlfw_msa_ready_send_sync_msg(penv); if (ret < 0) { if (ret < 0) { ignore_assert = true; ignore_assert = true; goto err_power_on; goto err_setup_msa; } } ret = wlfw_cap_send_sync_msg(penv); ret = wlfw_cap_send_sync_msg(penv); if (ret < 0) { if (ret < 0) { ignore_assert = true; ignore_assert = true; goto err_power_on; goto err_setup_msa; } } wlfw_dynamic_feature_mask_send_sync_msg(penv, wlfw_dynamic_feature_mask_send_sync_msg(penv, Loading @@ -911,6 +1041,9 @@ static int icnss_driver_event_server_arrive(void *data) return ret; return ret; err_setup_msa: icnss_assign_msa_perm_all(penv, ICNSS_MSA_PERM_HLOS_ALL); clear_bit(ICNSS_MSA0_ASSIGNED, &penv->state); err_power_on: err_power_on: icnss_hw_power_off(penv); icnss_hw_power_off(penv); clear_server: clear_server: Loading Loading @@ -1455,13 +1588,23 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, struct icnss_priv *priv = container_of(nb, struct icnss_priv, struct icnss_priv *priv = container_of(nb, struct icnss_priv, modem_ssr_nb); modem_ssr_nb); struct icnss_uevent_fw_down_data fw_down_data = {0}; struct icnss_uevent_fw_down_data fw_down_data = {0}; int ret; icnss_pr_vdbg("Modem-Notify: event %lu\n", code); icnss_pr_vdbg("Modem-Notify: event %lu\n", code); if (code == SUBSYS_AFTER_SHUTDOWN && if (code == SUBSYS_AFTER_SHUTDOWN && notif->crashed == CRASH_STATUS_ERR_FATAL) { notif->crashed == CRASH_STATUS_ERR_FATAL) { ret = icnss_assign_msa_perm_all(priv, ICNSS_MSA_PERM_HLOS_ALL); if (!ret) { icnss_pr_info("Collecting msa0 segment dump\n"); icnss_pr_info("Collecting msa0 segment dump\n"); icnss_msa0_ramdump(priv); icnss_msa0_ramdump(priv); icnss_assign_msa_perm_all(priv, ICNSS_MSA_PERM_WLAN_HW_RW); } else { icnss_pr_err("Not able to Collect msa0 segment dump, Apps permissions not assigned %d\n", ret); } goto out; goto out; } } Loading Loading @@ -2777,6 +2920,9 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv) case ICNSS_PD_RESTART: case ICNSS_PD_RESTART: seq_puts(s, "PD RESTART"); seq_puts(s, "PD RESTART"); continue; continue; case ICNSS_MSA0_ASSIGNED: seq_puts(s, "MSA0 ASSIGNED"); continue; case ICNSS_WLFW_EXISTS: case ICNSS_WLFW_EXISTS: seq_puts(s, "WLAN FW EXISTS"); seq_puts(s, "WLAN FW EXISTS"); continue; continue; Loading Loading @@ -3344,6 +3490,11 @@ static int icnss_resource_parse(struct icnss_priv *priv) goto out; goto out; } } if (of_property_read_bool(pdev->dev.of_node, "qcom,hyp_enabled")) priv->is_hyp_enabled = true; icnss_pr_dbg("Hypervisor enabled = %d\n", priv->is_hyp_enabled); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "membase"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "membase"); if (!res) { if (!res) { icnss_pr_err("Memory base not found in DT\n"); icnss_pr_err("Memory base not found in DT\n"); Loading Loading @@ -3593,6 +3744,9 @@ static int icnss_remove(struct platform_device *pdev) icnss_hw_power_off(penv); icnss_hw_power_off(penv); icnss_assign_msa_perm_all(penv, ICNSS_MSA_PERM_HLOS_ALL); clear_bit(ICNSS_MSA0_ASSIGNED, &penv->state); dev_set_drvdata(&pdev->dev, NULL); dev_set_drvdata(&pdev->dev, NULL); return 0; return 0; Loading
drivers/soc/qcom/icnss_private.h +17 −0 Original line number Original line Diff line number Diff line Loading @@ -148,6 +148,7 @@ enum icnss_driver_state { ICNSS_SSR_REGISTERED, ICNSS_SSR_REGISTERED, ICNSS_PDR_REGISTERED, ICNSS_PDR_REGISTERED, ICNSS_PD_RESTART, ICNSS_PD_RESTART, ICNSS_MSA0_ASSIGNED, ICNSS_WLFW_EXISTS, ICNSS_WLFW_EXISTS, ICNSS_SHUTDOWN_DONE, ICNSS_SHUTDOWN_DONE, ICNSS_HOST_TRIGGERED_PDR, ICNSS_HOST_TRIGGERED_PDR, Loading Loading @@ -276,10 +277,25 @@ struct wlfw_fw_version_info { char fw_build_timestamp[WLFW_MAX_TIMESTAMP_LEN + 1]; char fw_build_timestamp[WLFW_MAX_TIMESTAMP_LEN + 1]; }; }; enum icnss_msa_perm { ICNSS_MSA_PERM_HLOS_ALL = 0, ICNSS_MSA_PERM_WLAN_HW_RW = 1, ICNSS_MSA_PERM_MAX, }; #define ICNSS_MAX_VMIDS 4 struct icnss_mem_region_info { struct icnss_mem_region_info { uint64_t reg_addr; uint64_t reg_addr; uint32_t size; uint32_t size; uint8_t secure_flag; uint8_t secure_flag; enum icnss_msa_perm perm; }; struct icnss_msa_perm_list_t { int vmids[ICNSS_MAX_VMIDS]; int perms[ICNSS_MAX_VMIDS]; int nelems; }; }; struct icnss_priv { struct icnss_priv { Loading Loading @@ -356,6 +372,7 @@ struct icnss_priv { void __iomem *hang_event_data_va; void __iomem *hang_event_data_va; uint16_t hang_event_data_len; uint16_t hang_event_data_len; void *hang_event_data; void *hang_event_data; bool is_hyp_enabled; }; }; struct icnss_reg_info { struct icnss_reg_info { Loading