void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
                      bool ext)
 {
-       struct iwl_apply_point_data *data;
+       struct iwl_apply_point_data *dbg_cfg, *tlv_copy;
        struct iwl_fw_ini_header *header = (void *)&tlv->data[0];
+       u32 tlv_type = le32_to_cpu(tlv->type);
+       u32 len = le32_to_cpu(tlv->length);
        u32 apply_point = le32_to_cpu(header->apply_point);
 
-       int copy_size = le32_to_cpu(tlv->length) + sizeof(*tlv);
-       int offset_size = copy_size;
-
        if (le32_to_cpu(header->tlv_version) != 1)
                return;
 
        if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM,
-                     "Invalid apply point id %d\n", apply_point))
+                     "Invalid apply point %d\n", apply_point))
                return;
 
+       IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n",
+                    tlv_type, apply_point);
+
        if (ext)
-               data = &trans->dbg.apply_points_ext[apply_point];
+               dbg_cfg = &trans->dbg.apply_points_ext[apply_point];
        else
-               data = &trans->dbg.apply_points[apply_point];
-
-       /*
-        * Make sure we still have room to copy this TLV. Offset points to the
-        * location the last copy ended.
-        */
-       if (WARN_ONCE(data->offset + offset_size > data->size,
-                     "Not enough memory for apply point %d\n",
-                     apply_point))
-               return;
-
-       memcpy(data->data + data->offset, (void *)tlv, copy_size);
-       data->offset += offset_size;
-}
-
-void iwl_dbg_tlv_alloc(struct iwl_trans *trans, size_t len, const u8 *data,
-                      bool ext)
-{
-       struct iwl_ucode_tlv *tlv;
-       u32 size[IWL_FW_INI_APPLY_NUM] = {0};
-       int i;
-
-       while (len >= sizeof(*tlv)) {
-               u32 tlv_len, tlv_type, apply;
-               struct iwl_fw_ini_header *hdr;
-
-               len -= sizeof(*tlv);
-               tlv = (void *)data;
-
-               tlv_len = le32_to_cpu(tlv->length);
-               tlv_type = le32_to_cpu(tlv->type);
+               dbg_cfg = &trans->dbg.apply_points[apply_point];
 
-               if (len < tlv_len)
-                       return;
-
-               len -= ALIGN(tlv_len, 4);
-               data += sizeof(*tlv) + ALIGN(tlv_len, 4);
-
-               if (tlv_type < IWL_UCODE_TLV_DEBUG_BASE ||
-                   tlv_type > IWL_UCODE_TLV_DEBUG_MAX)
-                       continue;
-
-               hdr = (void *)&tlv->data[0];
-               apply = le32_to_cpu(hdr->apply_point);
-
-               if (le32_to_cpu(hdr->tlv_version) != 1)
-                       continue;
-
-               IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n",
-                            le32_to_cpu(tlv->type), apply);
-
-               if (WARN_ON(apply >= IWL_FW_INI_APPLY_NUM))
-                       continue;
-
-               size[apply] += sizeof(*tlv) + tlv_len;
+       tlv_copy = kzalloc(sizeof(*tlv_copy) + len, GFP_KERNEL);
+       if (!tlv_copy) {
+               IWL_ERR(trans, "WRT: No memory for TLV 0x%x, apply point %d\n",
+                       tlv_type, apply_point);
+               return;
        }
 
-       for (i = 0; i < ARRAY_SIZE(size); i++) {
-               void *mem;
+       INIT_LIST_HEAD(&tlv_copy->list);
+       memcpy(&tlv_copy->tlv, tlv, sizeof(*tlv) + len);
 
-               if (!size[i])
-                       continue;
+       if (!dbg_cfg->list.next)
+               INIT_LIST_HEAD(&dbg_cfg->list);
 
-               mem = kzalloc(size[i], GFP_KERNEL);
+       list_add_tail(&tlv_copy->list, &dbg_cfg->list);
 
-               if (!mem) {
-                       IWL_ERR(trans, "No memory for apply point %d\n", i);
-                       return;
-               }
+       trans->dbg.ini_valid = true;
+}
 
-               if (ext) {
-                       trans->dbg.apply_points_ext[i].data = mem;
-                       trans->dbg.apply_points_ext[i].size = size[i];
-               } else {
-                       trans->dbg.apply_points[i].data = mem;
-                       trans->dbg.apply_points[i].size = size[i];
-               }
+static void iwl_dbg_tlv_free_list(struct list_head *list)
+{
+       if (!list || !list->next)
+               return;
 
-               trans->dbg.ini_valid = true;
+       while (!list_empty(list)) {
+               struct iwl_apply_point_data *node =
+                       list_entry(list->next, typeof(*node), list);
+
+               list_del(&node->list);
+               kfree(node);
        }
 }
 
        int i;
 
        for (i = 0; i < ARRAY_SIZE(trans->dbg.apply_points); i++) {
-               kfree(trans->dbg.apply_points[i].data);
-               trans->dbg.apply_points[i].size = 0;
-               trans->dbg.apply_points[i].offset = 0;
+               struct iwl_apply_point_data *data;
+
+               data = &trans->dbg.apply_points[i];
+               iwl_dbg_tlv_free_list(&data->list);
 
-               kfree(trans->dbg.apply_points_ext[i].data);
-               trans->dbg.apply_points_ext[i].size = 0;
-               trans->dbg.apply_points_ext[i].offset = 0;
+               data = &trans->dbg.apply_points_ext[i];
+               iwl_dbg_tlv_free_list(&data->list);
        }
 }
 
        if (res)
                return;
 
-       iwl_dbg_tlv_alloc(trans, fw->size, fw->data, true);
        iwl_dbg_tlv_parse_bin(trans, fw->data, fw->size);
 
        trans->dbg.external_ini_loaded = true;