On Wed, Nov 12, 2025 at 10:28:51PM +0530, Aswin Murugan wrote:
> 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]>
> ---
>  drivers/smem/msm_smem.c | 56 +++++++++++++++++++++++++++++------------
>  1 file changed, 40 insertions(+), 16 deletions(-)

There was an earlier effort from Casey to import SMEM driver here [1]
from Linux kernel. But unfortunately that patch-set didn't got reworked
to make into U-Boot mainline.

Casey, do you have any plans to respin the patch-set? Or it's fine for
others to take over that patch-set?

[1] https://patchwork.ozlabs.org/project/uboot/list/?series=433987&state=*

-Sumit

> 
> 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,
> -- 
> 2.34.1
> 

Reply via email to