diff options
| author | Aswin Murugan <[email protected]> | 2025-11-12 22:28:51 +0530 |
|---|---|---|
| committer | Casey Connolly <[email protected]> | 2026-01-14 16:25:09 +0100 |
| commit | 984ebe2d553ba37cd92de2c093c73a07c16ea17c (patch) | |
| tree | edb2da7fe0e9230e10bf3c8933b59ea1300a816a | |
| parent | 63439561493f9159732da7be3e1f3d34ffdae030 (diff) | |
smem: msm: Fix memory-region lookup, direct <reg> mapping and update SMEM host count
The SMEM driver was failing to resolve memory regions on some boards
because `dev_of_offset()` + `fdtdec_lookup_phandle()` did not yield a
valid DT node. Modernize the code to use driver-model/ofnode accessors
and make the probe robust for both DT styles (direct `reg` vs
`memory-region` phandle).
- qcom_smem_map_memory():
* Drop fdtdec path; use dev_read_phandle_with_args() +
ofnode_read_resource().
* Use dev_read_phandle_with_args() +
fnode_read_resource().
- qcom_smem_probe():
* Try dev_read_addr_size() first (map via <reg>), else fall back to
qcom_smem_map_memory() with "memory-region".
* Check "qcom,rpm-msg-ram" presence to add second region.
- Additionally, SMEM_HOST_COUNT is increased to support newer SMEM
versions that include more remote processors. This avoids failures
during processor ID checks.
Signed-off-by: Aswin Murugan <[email protected]>
Reviewed-by: Varadarajan Narayanan <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Casey Connolly <[email protected]>
| -rw-r--r-- | drivers/smem/msm_smem.c | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/drivers/smem/msm_smem.c b/drivers/smem/msm_smem.c index ccd145f9afb..b6b92d3530d 100644 --- a/drivers/smem/msm_smem.c +++ b/drivers/smem/msm_smem.c @@ -88,7 +88,7 @@ DECLARE_GLOBAL_DATA_PTR; #define SMEM_GLOBAL_HOST 0xfffe /* Max number of processors/hosts in a system */ -#define SMEM_HOST_COUNT 10 +#define SMEM_HOST_COUNT 25 /** * struct smem_proc_comm - proc_comm communication struct (legacy) @@ -821,23 +821,34 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem, static int qcom_smem_map_memory(struct qcom_smem *smem, struct udevice *dev, const char *name, int i) { - struct fdt_resource r; int ret; - int node = dev_of_offset(dev); + struct ofnode_phandle_args args; + struct resource r; - ret = fdtdec_lookup_phandle(gd->fdt_blob, node, name); - if (ret < 0) { - dev_err(dev, "No %s specified\n", name); + if (!dev_read_prop(dev, name, NULL)) { + dev_err(dev, "%s prop not found\n", name); return -EINVAL; } - ret = fdt_get_resource(gd->fdt_blob, ret, "reg", 0, &r); - if (ret) - return ret; + ret = dev_read_phandle_with_args(dev, name, NULL, 0, 0, &args); + if (ret) { + dev_err(dev, "%s phandle read failed\n", name); + return -EINVAL; + } + if (!ofnode_valid(args.node)) { + dev_err(dev, "Invalid node from phandle args\n"); + return -EINVAL; + } + + ret = ofnode_read_resource(args.node, 0, &r); + if (ret) { + dev_err(dev, "Can't get mmap base address(%d)\n", ret); + return ret; + } smem->regions[i].aux_base = (u32)r.start; - smem->regions[i].size = fdt_resource_size(&r); - smem->regions[i].virt_base = devm_ioremap(dev, r.start, fdt_resource_size(&r)); + smem->regions[i].size = resource_size(&r); + smem->regions[i].virt_base = devm_ioremap(dev, r.start, resource_size(&r)); if (!smem->regions[i].virt_base) return -ENOMEM; @@ -852,10 +863,14 @@ static int qcom_smem_probe(struct udevice *dev) int num_regions; u32 version; int ret; - int node = dev_of_offset(dev); + fdt_addr_t addr; + fdt_size_t size; + + if (__smem) + return 0; num_regions = 1; - if (fdtdec_lookup_phandle(gd->fdt_blob, node, "qcomrpm-msg-ram") >= 0) + if (dev_read_prop(dev, "qcom,rpm-msg-ram", NULL)) num_regions++; array_size = num_regions * sizeof(struct smem_region); @@ -866,9 +881,18 @@ static int qcom_smem_probe(struct udevice *dev) smem->dev = dev; smem->num_regions = num_regions; - ret = qcom_smem_map_memory(smem, dev, "memory-region", 0); - if (ret) - return ret; + addr = dev_read_addr_size(dev, &size); + if (addr == FDT_ADDR_T_NONE) { + ret = qcom_smem_map_memory(smem, dev, "memory-region", 0); + if (ret) + return ret; + } else { + smem->regions[0].aux_base = (u32)addr; + smem->regions[0].size = size; + smem->regions[0].virt_base = devm_ioremap(dev, addr, size); + if (!smem->regions[0].virt_base) + return -ENOMEM; + } if (num_regions > 1) { ret = qcom_smem_map_memory(smem, dev, |
