| 921 | } |
| 922 | |
| 923 | static void its_map_release(struct rt_ref *r) |
| 924 | { |
| 925 | rt_ubase_t level; |
| 926 | struct gicv3_its *its; |
| 927 | struct its_table *tbl; |
| 928 | struct its_command cmd; |
| 929 | struct its_map *map = rt_container_of(r, struct its_map, ref); |
| 930 | |
| 931 | its = map->its; |
| 932 | tbl = its_baser_type(its, GITS_BASER_TYPE_DEVICE); |
| 933 | |
| 934 | rt_memset(&cmd, 0, sizeof(cmd)); |
| 935 | its_encode_cmd(&cmd, GITS_CMD_MAPD); |
| 936 | its_encode_device_id(&cmd, map->device_id); |
| 937 | its_encode_size(&cmd, rt_ilog2(tbl->itt_entries) - 1); |
| 938 | its_encode_itt(&cmd, (rt_uint64_t)rt_kmem_v2p(map->itt)); |
| 939 | its_encode_valid(&cmd, RT_FALSE); |
| 940 | its_cmd_submit(its, &cmd, map, RT_TRUE); |
| 941 | |
| 942 | level = rt_spin_lock_irqsave(&map_lock); |
| 943 | rt_list_insert_before(&map_nodes, &map->list); |
| 944 | rt_spin_unlock_irqrestore(&map_lock, level); |
| 945 | |
| 946 | if (map->itt) |
| 947 | { |
| 948 | rt_free_align(map->itt); |
| 949 | } |
| 950 | if (map->lvl2_dte) |
| 951 | { |
| 952 | if (rt_page_ref_get(map->lvl2_dte, tbl->lvl2_bits) == 1) |
| 953 | { |
| 954 | rt_uint64_t *entry; |
| 955 | |
| 956 | entry = tbl->base + (map->device_id / (tbl->page_size / GITS_LVL1_ENTRY_SIZE)); |
| 957 | *entry = rt_cpu_to_le64(0); |
| 958 | |
| 959 | if (!(tbl->val & GITS_BASER_SHARE_MASK_ALL)) |
| 960 | { |
| 961 | rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, entry, sizeof(*entry)); |
| 962 | } |
| 963 | } |
| 964 | rt_pages_free(map->lvl2_dte, tbl->lvl2_bits); |
| 965 | } |
| 966 | rt_free(map); |
| 967 | } |
| 968 | |
| 969 | static void gicv3_its_irq_free_msi(struct rt_pic *pic, int irq) |
| 970 | { |
nothing calls this directly
no test coverage detected