diff options
author | Arnd Bergmann <arnd@arndb.de> | 2019-09-12 13:46:20 +0200 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2019-09-12 13:46:20 +0200 |
commit | 3dc8dcb02fdba3370aec0696727e6adfe8033aa4 (patch) | |
tree | 554677270e03bbae10bfeff9347d85057f9e1fcf /drivers/firmware | |
parent | ef92bfdaa7123bc8bdaed3f0f6e008500dd555da (diff) | |
parent | 1709510221c57fd566479c228434ff9edd6435be (diff) | |
download | linux-3dc8dcb02fdba3370aec0696727e6adfe8033aa4.tar.bz2 |
Merge tag 'qcom-drivers-for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into arm/drivers
Qualcomm ARM Based Driver Updates for v5.4
* Add AOSS QMP support
* Various fixups for Qualcomm SCM
* Add socinfo driver
* Add SoC serial number attribute and associated APIs
* Add SM8150 and SC7180 support in Qualcomm SCM
* Fixup max processor count in SMEM
* tag 'qcom-drivers-for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux:
soc: qcom: aoss: Add AOSS QMP support
dt-bindings: soc: qcom: aoss: Add SM8150 and SC7180 support
dt-bindings: firmware: scm: Add SM8150 and SC7180 support
dt-bindings: firmware: scm: re-order compatible list
soc: qcom: smem: Update max processor count
soc: qcom: socinfo: Annotate switch cases with fall through
soc: qcom: Extend AOSS QMP driver to support resources that are used to wake up the SoC.
soc: qcom: socinfo: Expose image information
soc: qcom: socinfo: Expose custom attributes
soc: qcom: Add socinfo driver
base: soc: Export soc_device_register/unregister APIs
base: soc: Add serial_number attribute to soc
firmware: qcom_scm: Cleanup code in qcom_scm_assign_mem()
firmware: qcom_scm: Fix some typos in docs and printks
firmware: qcom_scm: Use proper types for dma mappings
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/qcom_scm.c | 47 |
1 files changed, 24 insertions, 23 deletions
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 2ddc118dba1b..4802ab170fe5 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -9,6 +9,7 @@ #include <linux/init.h> #include <linux/cpumask.h> #include <linux/export.h> +#include <linux/dma-direct.h> #include <linux/dma-mapping.h> #include <linux/module.h> #include <linux/types.h> @@ -425,21 +426,23 @@ 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, - 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; 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; @@ -447,52 +450,50 @@ 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) + 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; - 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, 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); + "Assign memory protection call failed %d\n", ret); return -EINVAL; } |