From 6e37ccf78a53296c6c7bf426065762c27829eb84 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 17 May 2019 14:09:21 -0700 Subject: firmware: qcom_scm: Use proper types for dma mappings We need to use the proper types and convert between physical addresses and dma addresses here to avoid mismatch warnings. This is especially important on systems with a different size for dma addresses and physical addresses. Otherwise, we get the following warning: drivers/firmware/qcom_scm.c: In function "qcom_scm_assign_mem": drivers/firmware/qcom_scm.c:469:47: error: passing argument 3 of "dma_alloc_coherent" from incompatible pointer type [-Werror=incompatible-pointer-types] We also fix the size argument to dma_free_coherent() because that size doesn't need to be aligned after it's already aligned on the allocation size. In fact, dma debugging expects the same arguments to be passed to both the allocation and freeing sides of the functions so changing the size is incorrect regardless. Reported-by: Ian Jackson Cc: Ian Jackson Cc: Julien Grall Cc: Bjorn Andersson Cc: Avaneesh Kumar Dwivedi Tested-by: Bjorn Andersson Signed-off-by: Stephen Boyd Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom_scm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/firmware') diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 2ddc118dba1b..74b84244a0db 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -440,6 +441,7 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, phys_addr_t mem_to_map_phys; phys_addr_t dest_phys; phys_addr_t ptr_phys; + dma_addr_t ptr_dma; size_t mem_to_map_sz; size_t dest_sz; size_t src_sz; @@ -457,9 +459,10 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, ptr_sz = ALIGN(src_sz, SZ_64) + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(dest_sz, SZ_64); - ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_phys, GFP_KERNEL); + ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_dma, GFP_KERNEL); if (!ptr) return -ENOMEM; + ptr_phys = dma_to_phys(__scm->dev, ptr_dma); /* Fill source vmid detail */ src = ptr; @@ -489,7 +492,7 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, ret = __qcom_scm_assign_mem(__scm->dev, mem_to_map_phys, mem_to_map_sz, ptr_phys, src_sz, dest_phys, dest_sz); - dma_free_coherent(__scm->dev, ALIGN(ptr_sz, SZ_64), ptr, ptr_phys); + dma_free_coherent(__scm->dev, ptr_sz, ptr, ptr_dma); if (ret) { dev_err(__scm->dev, "Assign memory protection call failed %d.\n", ret); -- cgit v1.2.3-59-g8ed1b From c8b08fc0d6f83427973b94694b7ec8855d2d1e37 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 17 May 2019 14:09:23 -0700 Subject: firmware: qcom_scm: Fix some typos in docs and printks Some words are misspelled and we put a full stop after a return value integer. Fix these things up so it doesn't look so odd. Cc: Ian Jackson Cc: Julien Grall Cc: Bjorn Andersson Cc: Avaneesh Kumar Dwivedi Signed-off-by: Stephen Boyd Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom_scm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/firmware') diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 74b84244a0db..c7e63af91567 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -426,11 +426,11 @@ EXPORT_SYMBOL(qcom_scm_set_remote_state); * @mem_sz: size of the region. * @srcvm: vmid for current set of owners, each set bit in * flag indicate a unique owner - * @newvm: array having new owners and corrsponding permission + * @newvm: array having new owners and corresponding permission * flags * @dest_cnt: number of owners in next set. * - * Return negative errno on failure, 0 on success, with @srcvm updated. + * Return negative errno on failure or 0 on success with @srcvm updated. */ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, unsigned int *srcvm, @@ -495,7 +495,7 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, dma_free_coherent(__scm->dev, ptr_sz, ptr, ptr_dma); if (ret) { dev_err(__scm->dev, - "Assign memory protection call failed %d.\n", ret); + "Assign memory protection call failed %d\n", ret); return -EINVAL; } -- cgit v1.2.3-59-g8ed1b From af311ff9a69189a03548efd5a47d4bb44644fd45 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 17 May 2019 14:09:22 -0700 Subject: firmware: qcom_scm: Cleanup code in qcom_scm_assign_mem() There are some questionable coding styles in this function. It looks quite odd to deref a pointer with array indexing that only uses the first element. Also, destroying an input/output variable halfway through the function and then overwriting it on success is not clear. It's better to use a local variable and the kernel macros to step through each bit set in a bitmask and clearly show where outputs are set. Cc: Ian Jackson Cc: Julien Grall Cc: Bjorn Andersson Cc: Avaneesh Kumar Dwivedi Tested-by: Bjorn Andersson Signed-off-by: Stephen Boyd [bjorn: Changed for_each_set_bit() size to BITS_PER_LONG] Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom_scm.c | 34 ++++++++++++++++------------------ include/linux/qcom_scm.h | 9 +++++---- 2 files changed, 21 insertions(+), 22 deletions(-) (limited to 'drivers/firmware') diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index c7e63af91567..4802ab170fe5 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -434,7 +434,8 @@ EXPORT_SYMBOL(qcom_scm_set_remote_state); */ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, unsigned int *srcvm, - struct qcom_scm_vmperm *newvm, int dest_cnt) + const struct qcom_scm_vmperm *newvm, + unsigned int dest_cnt) { struct qcom_scm_current_perm_info *destvm; struct qcom_scm_mem_map_info *mem_to_map; @@ -449,11 +450,10 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, int next_vm; __le32 *src; void *ptr; - int ret; - int len; - int i; + int ret, i, b; + unsigned long srcvm_bits = *srcvm; - src_sz = hweight_long(*srcvm) * sizeof(*src); + src_sz = hweight_long(srcvm_bits) * sizeof(*src); mem_to_map_sz = sizeof(*mem_to_map); dest_sz = dest_cnt * sizeof(*destvm); ptr_sz = ALIGN(src_sz, SZ_64) + ALIGN(mem_to_map_sz, SZ_64) + @@ -466,28 +466,26 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, /* Fill source vmid detail */ src = ptr; - len = hweight_long(*srcvm); - for (i = 0; i < len; i++) { - src[i] = cpu_to_le32(ffs(*srcvm) - 1); - *srcvm ^= 1 << (ffs(*srcvm) - 1); - } + i = 0; + for_each_set_bit(b, &srcvm_bits, BITS_PER_LONG) + src[i++] = cpu_to_le32(b); /* Fill details of mem buff to map */ mem_to_map = ptr + ALIGN(src_sz, SZ_64); mem_to_map_phys = ptr_phys + ALIGN(src_sz, SZ_64); - mem_to_map[0].mem_addr = cpu_to_le64(mem_addr); - mem_to_map[0].mem_size = cpu_to_le64(mem_sz); + mem_to_map->mem_addr = cpu_to_le64(mem_addr); + mem_to_map->mem_size = cpu_to_le64(mem_sz); next_vm = 0; /* Fill details of next vmid detail */ destvm = ptr + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(src_sz, SZ_64); dest_phys = ptr_phys + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(src_sz, SZ_64); - for (i = 0; i < dest_cnt; i++) { - destvm[i].vmid = cpu_to_le32(newvm[i].vmid); - destvm[i].perm = cpu_to_le32(newvm[i].perm); - destvm[i].ctx = 0; - destvm[i].ctx_size = 0; - next_vm |= BIT(newvm[i].vmid); + for (i = 0; i < dest_cnt; i++, destvm++, newvm++) { + destvm->vmid = cpu_to_le32(newvm->vmid); + destvm->perm = cpu_to_le32(newvm->perm); + destvm->ctx = 0; + destvm->ctx_size = 0; + next_vm |= BIT(newvm->vmid); } ret = __qcom_scm_assign_mem(__scm->dev, mem_to_map_phys, mem_to_map_sz, diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 3f12cc77fb58..2d5eff506e13 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -49,8 +49,9 @@ extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, extern int qcom_scm_pas_auth_and_reset(u32 peripheral); extern int qcom_scm_pas_shutdown(u32 peripheral); extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, - unsigned int *src, struct qcom_scm_vmperm *newvm, - int dest_cnt); + unsigned int *src, + const struct qcom_scm_vmperm *newvm, + unsigned int dest_cnt); extern void qcom_scm_cpu_power_down(u32 flags); extern u32 qcom_scm_get_version(void); extern int qcom_scm_set_remote_state(u32 state, u32 id); @@ -87,8 +88,8 @@ qcom_scm_pas_auth_and_reset(u32 peripheral) { return -ENODEV; } static inline int qcom_scm_pas_shutdown(u32 peripheral) { return -ENODEV; } static inline int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, unsigned int *src, - struct qcom_scm_vmperm *newvm, - int dest_cnt) { return -ENODEV; } + const struct qcom_scm_vmperm *newvm, + unsigned int dest_cnt) { return -ENODEV; } static inline void qcom_scm_cpu_power_down(u32 flags) {} static inline u32 qcom_scm_get_version(void) { return 0; } static inline u32 -- cgit v1.2.3-59-g8ed1b