/* Processor/host identifier for the global partition */
#define SMEM_GLOBAL_HOST 0xfffe
-/* Max number of processors/hosts in a system */
-#define SMEM_HOST_COUNT 25
-
/**
* struct smem_proc_comm - proc_comm communication struct (legacy)
* @command: current command to be executed
struct platform_device *socinfo;
struct smem_ptable *ptable;
struct smem_partition global_partition;
- struct smem_partition partitions[SMEM_HOST_COUNT];
+ struct xarray partitions;
unsigned num_regions;
struct smem_region regions[] __counted_by(num_regions);
int qcom_smem_bust_hwspin_lock_by_host(unsigned int host)
{
/* This function is for remote procs, so ignore SMEM_HOST_APPS */
- if (host == SMEM_HOST_APPS || host >= SMEM_HOST_COUNT)
+ if (host == SMEM_HOST_APPS || !xa_load(&__smem->partitions, host))
return -EINVAL;
return hwspin_lock_bust(__smem->hwlock, SMEM_HOST_ID_TO_HWSPINLOCK_ID(host));
if (ret)
return ret;
- if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) {
- part = &__smem->partitions[host];
+ part = xa_load(&__smem->partitions, host);
+ if (part) {
ret = qcom_smem_alloc_private(__smem, part, item, size);
} else if (__smem->global_partition.virt_base) {
part = &__smem->global_partition;
if (item >= __smem->item_count)
return ERR_PTR(-EINVAL);
- if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) {
- part = &__smem->partitions[host];
+ part = xa_load(&__smem->partitions, host);
+ if (part) {
ptr = qcom_smem_get_private(__smem, part, item, size);
} else if (__smem->global_partition.virt_base) {
part = &__smem->global_partition;
if (IS_ERR(__smem))
return PTR_ERR(__smem);
- if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) {
- part = &__smem->partitions[host];
+ part = xa_load(&__smem->partitions, host);
+ if (part) {
phdr = part->virt_base;
ret = le32_to_cpu(phdr->offset_free_cached) -
le32_to_cpu(phdr->offset_free_uncached);
{
struct smem_partition *part;
struct smem_region *area;
+ unsigned long index;
u64 offset;
u32 i;
- for (i = 0; i < SMEM_HOST_COUNT; i++) {
- part = &__smem->partitions[i];
-
+ xa_for_each(&__smem->partitions, index, part) {
if (addr_in_range(part->virt_base, part->size, p)) {
offset = p - part->virt_base;
qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host)
{
struct smem_partition_header *header;
+ struct smem_partition *part;
struct smem_ptable_entry *entry;
struct smem_ptable *ptable;
u16 remote_host;
u16 host0, host1;
+ int ret;
int i;
ptable = qcom_smem_get_ptable(smem);
if (IS_ERR(ptable))
return PTR_ERR(ptable);
+ xa_init(&smem->partitions);
+
for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) {
entry = &ptable->entry[i];
if (!le32_to_cpu(entry->offset))
else
continue;
- if (remote_host >= SMEM_HOST_COUNT) {
- dev_err(smem->dev, "bad host %u\n", remote_host);
- return -EINVAL;
- }
-
- if (smem->partitions[remote_host].virt_base) {
+ if (xa_load(&smem->partitions, remote_host)) {
dev_err(smem->dev, "duplicate host %u\n", remote_host);
return -EINVAL;
}
if (!header)
return -EINVAL;
- smem->partitions[remote_host].virt_base = (void __iomem *)header;
- smem->partitions[remote_host].phys_base = smem->regions[0].aux_base +
- le32_to_cpu(entry->offset);
- smem->partitions[remote_host].size = le32_to_cpu(entry->size);
- smem->partitions[remote_host].cacheline = le32_to_cpu(entry->cacheline);
+ part = devm_kzalloc(smem->dev, sizeof(struct smem_partition), GFP_KERNEL);
+ if (!part)
+ return -ENOMEM;
+
+ part->virt_base = (void __iomem *)header;
+ part->phys_base = smem->regions[0].aux_base + le32_to_cpu(entry->offset);
+ part->size = le32_to_cpu(entry->size);
+ part->cacheline = le32_to_cpu(entry->cacheline);
+
+ ret = xa_insert(&smem->partitions, remote_host, part, GFP_KERNEL);
+ if (ret) {
+ dev_err(smem->dev, "fail to insert host %u\n", remote_host);
+ return ret;
+ }
}
return 0;
return -EINVAL;
}
- BUILD_BUG_ON(SMEM_HOST_APPS >= SMEM_HOST_COUNT);
ret = qcom_smem_enumerate_partitions(smem, SMEM_HOST_APPS);
if (ret < 0 && ret != -ENOENT)
return ret;
{
platform_device_unregister(__smem->socinfo);
+ xa_destroy(&__smem->partitions);
/* Set to -EPROBE_DEFER to signal unprobed state */
__smem = ERR_PTR(-EPROBE_DEFER);
}