|
|
@@ -715,10 +715,13 @@ static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc,
|
|
|
if (!mapping)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- ret = iommu_map(rproc->domain, rsc->da, rsc->pa, rsc->len, rsc->flags);
|
|
|
- if (ret) {
|
|
|
- dev_err(dev, "failed to map devmem: %d\n", ret);
|
|
|
- goto out;
|
|
|
+ if (!rproc->late_attach) {
|
|
|
+ ret = iommu_map(rproc->domain, rsc->da, rsc->pa, rsc->len,
|
|
|
+ rsc->flags);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(dev, "failed to map devmem: %d\n", ret);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -733,8 +736,12 @@ static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc,
|
|
|
mapping->len = rsc->len;
|
|
|
list_add_tail(&mapping->node, &rproc->mappings);
|
|
|
|
|
|
- dev_dbg(dev, "mapped devmem pa 0x%x, da 0x%x, len 0x%x\n",
|
|
|
- rsc->pa, rsc->da, rsc->len);
|
|
|
+ if (!rproc->late_attach)
|
|
|
+ dev_dbg(dev, "mapped devmem pa 0x%x, da 0x%x, len 0x%x\n",
|
|
|
+ rsc->pa, rsc->da, rsc->len);
|
|
|
+ else
|
|
|
+ dev_dbg(dev, "late-attach: processed devmem pa 0x%x, da 0x%x, len 0x%x\n",
|
|
|
+ rsc->pa, rsc->da, rsc->len);
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
@@ -824,11 +831,13 @@ static int rproc_handle_carveout(struct rproc *rproc,
|
|
|
goto dma_free;
|
|
|
}
|
|
|
|
|
|
- ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len,
|
|
|
- rsc->flags);
|
|
|
- if (ret) {
|
|
|
- dev_err(dev, "iommu_map failed: %d\n", ret);
|
|
|
- goto free_mapping;
|
|
|
+ if (!rproc->late_attach) {
|
|
|
+ ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len,
|
|
|
+ rsc->flags);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(dev, "iommu_map failed: %d\n", ret);
|
|
|
+ goto free_mapping;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -842,8 +851,13 @@ static int rproc_handle_carveout(struct rproc *rproc,
|
|
|
mapping->len = rsc->len;
|
|
|
list_add_tail(&mapping->node, &rproc->mappings);
|
|
|
|
|
|
- dev_dbg(dev, "carveout mapped 0x%x to %pad\n",
|
|
|
- rsc->da, &dma);
|
|
|
+ if (!rproc->late_attach)
|
|
|
+ dev_dbg(dev, "carveout mapped 0x%x to %pad\n",
|
|
|
+ rsc->da, &dma);
|
|
|
+ else
|
|
|
+ dev_dbg(dev, "late-attach: carveout processed 0x%x to %pad\n",
|
|
|
+ rsc->da, &dma);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -1116,11 +1130,14 @@ static void rproc_resource_cleanup(struct rproc *rproc)
|
|
|
list_for_each_entry_safe(entry, tmp, &rproc->mappings, node) {
|
|
|
size_t unmapped;
|
|
|
|
|
|
- unmapped = iommu_unmap(rproc->domain, entry->da, entry->len);
|
|
|
- if (unmapped != entry->len) {
|
|
|
- /* nothing much to do besides complaining */
|
|
|
- dev_err(dev, "failed to unmap %u/%zu\n", entry->len,
|
|
|
- unmapped);
|
|
|
+ if (!rproc->late_attach) {
|
|
|
+ unmapped = iommu_unmap(rproc->domain, entry->da,
|
|
|
+ entry->len);
|
|
|
+ if (unmapped != entry->len) {
|
|
|
+ /* nothing much to do besides complaining */
|
|
|
+ dev_err(dev, "failed to unmap %u/%zu\n",
|
|
|
+ entry->len, unmapped);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
list_del(&entry->node);
|
|
|
@@ -1189,7 +1206,7 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
|
|
|
goto clean_up_resources;
|
|
|
}
|
|
|
|
|
|
- if (!rproc->skip_load) {
|
|
|
+ if (!rproc->skip_load && !rproc->late_attach) {
|
|
|
/* load the ELF segments to memory */
|
|
|
ret = rproc_load_segments(rproc, fw);
|
|
|
if (ret) {
|
|
|
@@ -1197,6 +1214,8 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
|
|
|
ret);
|
|
|
goto clean_up_resources;
|
|
|
}
|
|
|
+ } else {
|
|
|
+ dev_dbg(dev, "Skipped program segments load for pre-booted rproc\n");
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -1640,6 +1659,7 @@ void rproc_shutdown(struct rproc *rproc)
|
|
|
complete_all(&rproc->crash_comp);
|
|
|
|
|
|
rproc->state = RPROC_OFFLINE;
|
|
|
+ rproc->late_attach = 0;
|
|
|
|
|
|
dev_info(dev, "stopped remote processor %s\n", rproc->name);
|
|
|
|