return data;
 }
 
-static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,
-                                          const u8 *data, size_t len)
+static int iwl_uefi_reduce_power_section(struct iwl_trans *trans,
+                                        const u8 *data, size_t len,
+                                        struct iwl_pnvm_image *pnvm_data)
 {
        const struct iwl_ucode_tlv *tlv;
-       u8 *reduce_power_data = NULL, *tmp;
-       u32 size = 0;
 
        IWL_DEBUG_FW(trans, "Handling REDUCE_POWER section\n");
+       memset(pnvm_data, 0, sizeof(*pnvm_data));
 
        while (len >= sizeof(*tlv)) {
                u32 tlv_len, tlv_type;
                if (len < tlv_len) {
                        IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
                                len, tlv_len);
-                       kfree(reduce_power_data);
-                       reduce_power_data = ERR_PTR(-EINVAL);
-                       goto out;
+                       return -EINVAL;
                }
 
                data += sizeof(*tlv);
                                     "Got IWL_UCODE_TLV_MEM_DESC len %d\n",
                                     tlv_len);
 
-                       IWL_DEBUG_FW(trans, "Adding data (size %d)\n", tlv_len);
-
-                       tmp = krealloc(reduce_power_data, size + tlv_len, GFP_KERNEL);
-                       if (!tmp) {
+                       if (pnvm_data->n_chunks == IPC_DRAM_MAP_ENTRY_NUM_MAX) {
                                IWL_DEBUG_FW(trans,
-                                            "Couldn't allocate (more) reduce_power_data\n");
-
-                               kfree(reduce_power_data);
-                               reduce_power_data = ERR_PTR(-ENOMEM);
-                               goto out;
+                               "too many payloads to allocate in DRAM.\n");
+                               return -EINVAL;
                        }
 
-                       reduce_power_data = tmp;
-
-                       memcpy(reduce_power_data + size, data, tlv_len);
+                       IWL_DEBUG_FW(trans, "Adding data (size %d)\n", tlv_len);
 
-                       size += tlv_len;
+                       pnvm_data->chunks[pnvm_data->n_chunks].data = data;
+                       pnvm_data->chunks[pnvm_data->n_chunks].len = tlv_len;
+                       pnvm_data->n_chunks++;
 
                        break;
                }
        }
 
 done:
-       if (!size) {
+       if (!pnvm_data->n_chunks) {
                IWL_DEBUG_FW(trans, "Empty REDUCE_POWER, skipping.\n");
-               /* Better safe than sorry, but 'reduce_power_data' should
-                * always be NULL if !size.
-                */
-               kfree(reduce_power_data);
-               reduce_power_data = ERR_PTR(-ENOENT);
-               goto out;
+               return -ENOENT;
        }
-
-       IWL_INFO(trans, "loaded REDUCE_POWER\n");
-
-out:
-       return reduce_power_data;
+       return 0;
 }
 
-static void *iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
-                                        const u8 *data, size_t len)
+static int iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
+                                      const u8 *data, size_t len,
+                                      struct iwl_pnvm_image *pnvm_data)
 {
        const struct iwl_ucode_tlv *tlv;
-       void *sec_data;
 
        IWL_DEBUG_FW(trans, "Parsing REDUCE_POWER data\n");
 
                if (len < tlv_len) {
                        IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
                                len, tlv_len);
-                       return ERR_PTR(-EINVAL);
+                       return -EINVAL;
                }
 
                if (tlv_type == IWL_UCODE_TLV_PNVM_SKU) {
                        if (trans->sku_id[0] == le32_to_cpu(sku_id->data[0]) &&
                            trans->sku_id[1] == le32_to_cpu(sku_id->data[1]) &&
                            trans->sku_id[2] == le32_to_cpu(sku_id->data[2])) {
-                               sec_data = iwl_uefi_reduce_power_section(trans,
-                                                                        data,
-                                                                        len);
-                               if (!IS_ERR(sec_data))
-                                       return sec_data;
+                               int ret = iwl_uefi_reduce_power_section(trans,
+                                                                   data, len,
+                                                                   pnvm_data);
+                               if (!ret)
+                                       return 0;
                        } else {
                                IWL_DEBUG_FW(trans, "SKU ID didn't match!\n");
                        }
                }
        }
 
-       return ERR_PTR(-ENOENT);
+       return -ENOENT;
 }
 
-void *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)
+int iwl_uefi_get_reduced_power(struct iwl_trans *trans,
+                              struct iwl_pnvm_image *pnvm_data)
 {
        struct pnvm_sku_package *package;
-       void *data = NULL;
        unsigned long package_size;
        efi_status_t status;
-
-       *len = 0;
+       int ret;
+       size_t len = 0;
 
        if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
-               return ERR_PTR(-ENODEV);
+               return -ENODEV;
 
        /*
         * TODO: we hardcode a maximum length here, because reading
 
        package = kmalloc(package_size, GFP_KERNEL);
        if (!package)
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
 
        status = efi.get_variable(IWL_UEFI_REDUCED_POWER_NAME, &IWL_EFI_VAR_GUID,
                                  NULL, &package_size, package);
                             "Reduced Power UEFI variable not found 0x%lx (len %lu)\n",
                             status, package_size);
                kfree(package);
-               return ERR_PTR(-ENOENT);
+               return -ENOENT;
        }
 
        IWL_DEBUG_FW(trans, "Read reduced power from UEFI with size %lu\n",
                     package_size);
-       *len = package_size;
+       len = package_size;
 
        IWL_DEBUG_FW(trans, "rev %d, total_size %d, n_skus %d\n",
                     package->rev, package->total_size, package->n_skus);
 
-       data = iwl_uefi_reduce_power_parse(trans, package->data,
-                                          *len - sizeof(*package));
+       ret = iwl_uefi_reduce_power_parse(trans, package->data,
+                                         len - sizeof(*package),
+                                         pnvm_data);
 
        kfree(package);
 
-       return data;
+       return ret;
 }
 
 static int iwl_uefi_step_parse(struct uefi_cnv_common_step_data *common_step_data,
 
 }
 
 int iwl_trans_pcie_ctx_info_gen3_load_reduce_power(struct iwl_trans *trans,
-                                                  const void *data,
-                                                  u32 len)
+                                                  const struct iwl_pnvm_image *payloads)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl =
                &trans_pcie->prph_scratch->ctrl_cfg;
-       int ret;
+       struct iwl_dram_data *dram = &trans_pcie->reduce_power_dram;
 
        if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
                return 0;
 
-       /* only allocate the DRAM if not allocated yet */
-       if (!trans->reduce_power_loaded) {
-               if (WARN_ON(prph_sc_ctrl->reduce_power_cfg.size))
-                       return -EBUSY;
+       if (WARN_ON(prph_sc_ctrl->reduce_power_cfg.size))
+               return -EBUSY;
 
-               ret = iwl_pcie_ctxt_info_alloc_dma(trans, data, len,
-                                          &trans_pcie->reduce_power_dram);
-               if (ret < 0) {
-                       IWL_DEBUG_FW(trans,
-                                    "Failed to allocate reduce power DMA %d.\n",
-                                    ret);
-                       return ret;
-               }
-       }
+       /* only allocate the DRAM if not allocated yet */
+       if (!trans->reduce_power_loaded)
+               return iwl_pcie_load_payloads_continuously(trans,
+                                                          payloads,
+                                                          dram);
        return 0;
 }