Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

remoteproc: add is_iomem to da_to_va

Introduce an extra parameter is_iomem to da_to_va, then the caller
could take the memory as normal memory or io mapped memory.

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Link: https://lore.kernel.org/r/1615029865-23312-5-git-send-email-peng.fan@oss.nxp.com
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>

authored by

Peng Fan and committed by
Bjorn Andersson
40df0a91 2cfc056e

+45 -29
+1 -1
drivers/remoteproc/imx_rproc.c
··· 208 208 return -ENOENT; 209 209 } 210 210 211 - static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) 211 + static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 212 212 { 213 213 struct imx_rproc *priv = rproc->priv; 214 214 void *va = NULL;
+1 -1
drivers/remoteproc/ingenic_rproc.c
··· 121 121 writel(vqid, vpu->aux_base + REG_CORE_MSG); 122 122 } 123 123 124 - static void *ingenic_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) 124 + static void *ingenic_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 125 125 { 126 126 struct vpu *vpu = rproc->priv; 127 127 void __iomem *va = NULL;
+1 -1
drivers/remoteproc/keystone_remoteproc.c
··· 246 246 * can be used either by the remoteproc core for loading (when using kernel 247 247 * remoteproc loader), or by any rpmsg bus drivers. 248 248 */ 249 - static void *keystone_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) 249 + static void *keystone_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 250 250 { 251 251 struct keystone_rproc *ksproc = rproc->priv; 252 252 void __iomem *va = NULL;
+3 -3
drivers/remoteproc/mtk_scp.c
··· 272 272 } 273 273 274 274 /* grab the kernel address for this device address */ 275 - ptr = (void __iomem *)rproc_da_to_va(rproc, da, memsz); 275 + ptr = (void __iomem *)rproc_da_to_va(rproc, da, memsz, NULL); 276 276 if (!ptr) { 277 277 dev_err(dev, "bad phdr da 0x%x mem 0x%x\n", da, memsz); 278 278 ret = -EINVAL; ··· 509 509 return NULL; 510 510 } 511 511 512 - static void *scp_da_to_va(struct rproc *rproc, u64 da, size_t len) 512 + static void *scp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 513 513 { 514 514 struct mtk_scp *scp = (struct mtk_scp *)rproc->priv; 515 515 ··· 627 627 { 628 628 void *ptr; 629 629 630 - ptr = scp_da_to_va(scp->rproc, mem_addr, 0); 630 + ptr = scp_da_to_va(scp->rproc, mem_addr, 0, NULL); 631 631 if (!ptr) 632 632 return ERR_PTR(-EINVAL); 633 633
+1 -1
drivers/remoteproc/omap_remoteproc.c
··· 728 728 * Return: translated virtual address in kernel memory space on success, 729 729 * or NULL on failure. 730 730 */ 731 - static void *omap_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) 731 + static void *omap_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 732 732 { 733 733 struct omap_rproc *oproc = rproc->priv; 734 734 int i;
+1 -1
drivers/remoteproc/pru_rproc.c
··· 465 465 * core for any PRU client drivers. The PRU Instruction RAM access is restricted 466 466 * only to the PRU loader code. 467 467 */ 468 - static void *pru_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) 468 + static void *pru_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 469 469 { 470 470 struct pru_rproc *pru = rproc->priv; 471 471
+1 -1
drivers/remoteproc/qcom_q6v5_adsp.c
··· 281 281 return ret; 282 282 } 283 283 284 - static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len) 284 + static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 285 285 { 286 286 struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; 287 287 int offset;
+1 -1
drivers/remoteproc/qcom_q6v5_pas.c
··· 242 242 return ret; 243 243 } 244 244 245 - static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len) 245 + static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 246 246 { 247 247 struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; 248 248 int offset;
+1 -1
drivers/remoteproc/qcom_q6v5_wcss.c
··· 410 410 return 0; 411 411 } 412 412 413 - static void *q6v5_wcss_da_to_va(struct rproc *rproc, u64 da, size_t len) 413 + static void *q6v5_wcss_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 414 414 { 415 415 struct q6v5_wcss *wcss = rproc->priv; 416 416 int offset;
+1 -1
drivers/remoteproc/qcom_wcnss.c
··· 320 320 return ret; 321 321 } 322 322 323 - static void *wcnss_da_to_va(struct rproc *rproc, u64 da, size_t len) 323 + static void *wcnss_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 324 324 { 325 325 struct qcom_wcnss *wcnss = (struct qcom_wcnss *)rproc->priv; 326 326 int offset;
+5 -2
drivers/remoteproc/remoteproc_core.c
··· 189 189 * here the output of the DMA API for the carveouts, which should be more 190 190 * correct. 191 191 */ 192 - void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) 192 + void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 193 193 { 194 194 struct rproc_mem_entry *carveout; 195 195 void *ptr = NULL; 196 196 197 197 if (rproc->ops->da_to_va) { 198 - ptr = rproc->ops->da_to_va(rproc, da, len); 198 + ptr = rproc->ops->da_to_va(rproc, da, len, is_iomem); 199 199 if (ptr) 200 200 goto out; 201 201 } ··· 216 216 continue; 217 217 218 218 ptr = carveout->va + offset; 219 + 220 + if (is_iomem) 221 + *is_iomem = carveout->is_iomem; 219 222 220 223 break; 221 224 }
+6 -2
drivers/remoteproc/remoteproc_coredump.c
··· 153 153 size_t offset, size_t size) 154 154 { 155 155 void *ptr; 156 + bool is_iomem; 156 157 157 158 if (segment->dump) { 158 159 segment->dump(rproc, segment, dest, offset, size); 159 160 } else { 160 - ptr = rproc_da_to_va(rproc, segment->da + offset, size); 161 + ptr = rproc_da_to_va(rproc, segment->da + offset, size, &is_iomem); 161 162 if (!ptr) { 162 163 dev_err(&rproc->dev, 163 164 "invalid copy request for segment %pad with offset %zu and size %zu)\n", 164 165 &segment->da, offset, size); 165 166 memset(dest, 0xff, size); 166 167 } else { 167 - memcpy(dest, ptr, size); 168 + if (is_iomem) 169 + memcpy_fromio(dest, ptr, size); 170 + else 171 + memcpy(dest, ptr, size); 168 172 } 169 173 } 170 174 }
+1 -1
drivers/remoteproc/remoteproc_debugfs.c
··· 132 132 char buf[100]; 133 133 int len; 134 134 135 - va = rproc_da_to_va(data->rproc, trace->da, trace->len); 135 + va = rproc_da_to_va(data->rproc, trace->da, trace->len, NULL); 136 136 137 137 if (!va) { 138 138 len = scnprintf(buf, sizeof(buf), "Trace %s not available\n",
+15 -6
drivers/remoteproc/remoteproc_elf_loader.c
··· 175 175 u64 offset = elf_phdr_get_p_offset(class, phdr); 176 176 u32 type = elf_phdr_get_p_type(class, phdr); 177 177 void *ptr; 178 + bool is_iomem; 178 179 179 180 if (type != PT_LOAD) 180 181 continue; ··· 205 204 } 206 205 207 206 /* grab the kernel address for this device address */ 208 - ptr = rproc_da_to_va(rproc, da, memsz); 207 + ptr = rproc_da_to_va(rproc, da, memsz, &is_iomem); 209 208 if (!ptr) { 210 209 dev_err(dev, "bad phdr da 0x%llx mem 0x%llx\n", da, 211 210 memsz); ··· 214 213 } 215 214 216 215 /* put the segment where the remote processor expects it */ 217 - if (filesz) 218 - memcpy(ptr, elf_data + offset, filesz); 216 + if (filesz) { 217 + if (is_iomem) 218 + memcpy_fromio(ptr, (void __iomem *)(elf_data + offset), filesz); 219 + else 220 + memcpy(ptr, elf_data + offset, filesz); 221 + } 219 222 220 223 /* 221 224 * Zero out remaining memory for this segment. ··· 228 223 * did this for us. albeit harmless, we may consider removing 229 224 * this. 230 225 */ 231 - if (memsz > filesz) 232 - memset(ptr + filesz, 0, memsz - filesz); 226 + if (memsz > filesz) { 227 + if (is_iomem) 228 + memset_io((void __iomem *)(ptr + filesz), 0, memsz - filesz); 229 + else 230 + memset(ptr + filesz, 0, memsz - filesz); 231 + } 233 232 } 234 233 235 234 return ret; ··· 386 377 return NULL; 387 378 } 388 379 389 - return rproc_da_to_va(rproc, sh_addr, sh_size); 380 + return rproc_da_to_va(rproc, sh_addr, sh_size, NULL); 390 381 } 391 382 EXPORT_SYMBOL(rproc_elf_find_loaded_rsc_table);
+1 -1
drivers/remoteproc/remoteproc_internal.h
··· 84 84 void rproc_free_vring(struct rproc_vring *rvring); 85 85 int rproc_alloc_vring(struct rproc_vdev *rvdev, int i); 86 86 87 - void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len); 87 + void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem); 88 88 phys_addr_t rproc_va_to_pa(void *cpu_addr); 89 89 int rproc_trigger_recovery(struct rproc *rproc); 90 90
+1 -1
drivers/remoteproc/st_slim_rproc.c
··· 174 174 return 0; 175 175 } 176 176 177 - static void *slim_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) 177 + static void *slim_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 178 178 { 179 179 struct st_slim_rproc *slim_rproc = rproc->priv; 180 180 void *va = NULL;
+1 -1
drivers/remoteproc/ti_k3_dsp_remoteproc.c
··· 354 354 * can be used either by the remoteproc core for loading (when using kernel 355 355 * remoteproc loader), or by any rpmsg bus drivers. 356 356 */ 357 - static void *k3_dsp_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) 357 + static void *k3_dsp_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 358 358 { 359 359 struct k3_dsp_rproc *kproc = rproc->priv; 360 360 void __iomem *va = NULL;
+1 -1
drivers/remoteproc/ti_k3_r5_remoteproc.c
··· 590 590 * present in a DSP or IPU device). The translated addresses can be used 591 591 * either by the remoteproc core for loading, or by any rpmsg bus drivers. 592 592 */ 593 - static void *k3_r5_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) 593 + static void *k3_r5_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 594 594 { 595 595 struct k3_r5_rproc *kproc = rproc->priv; 596 596 struct k3_r5_core *core = kproc->core;
+1 -1
drivers/remoteproc/wkup_m3_rproc.c
··· 89 89 return error; 90 90 } 91 91 92 - static void *wkup_m3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) 92 + static void *wkup_m3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 93 93 { 94 94 struct wkup_m3_rproc *wkupm3 = rproc->priv; 95 95 void *va = NULL;
+1 -1
include/linux/remoteproc.h
··· 386 386 int (*stop)(struct rproc *rproc); 387 387 int (*attach)(struct rproc *rproc); 388 388 void (*kick)(struct rproc *rproc, int vqid); 389 - void * (*da_to_va)(struct rproc *rproc, u64 da, size_t len); 389 + void * (*da_to_va)(struct rproc *rproc, u64 da, size_t len, bool *is_iomem); 390 390 int (*parse_fw)(struct rproc *rproc, const struct firmware *fw); 391 391 int (*handle_rsc)(struct rproc *rproc, u32 rsc_type, void *rsc, 392 392 int offset, int avail);