Older Qualcomm SoCs (e.g. msm8953) have a qcom,rpm-proc with an smd-edge
subnode without compatible, which breaks probing any devices underneath
smd-edge like rpmcc. Manually find and bind nop_parent to smd-edge so
that probing of child devices can continue.

Example devicetree hierarchy:

  /remoteproc -> qcom,rpm-proc
      smd-edge -> (no compatible)
          rpm-requests -> qcom,smd-rpm
              clock-controller -> qcom,rpmcc
              power-controller -> qcom,*-rpmpd

Signed-off-by: Luca Weiss <[email protected]>
---
 drivers/clk/clk-stub.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-stub.c b/drivers/clk/clk-stub.c
index 4a6c71016da..6daf0efa8d0 100644
--- a/drivers/clk/clk-stub.c
+++ b/drivers/clk/clk-stub.c
@@ -9,10 +9,10 @@
 
 #include <clk-uclass.h>
 #include <dm.h>
+#include <dm/lists.h>
 
 /* NOP parent nodes to stub clocks */
 static const struct udevice_id nop_parent_ids[] = {
-       { .compatible = "qcom,rpm-proc" },
        { .compatible = "qcom,glink-rpm" },
        { .compatible = "qcom,glink-smd-rpm" },
        { }
@@ -26,6 +26,40 @@ U_BOOT_DRIVER(nop_parent) = {
        .flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
 };
 
+int rpm_proc_bind(struct udevice *dev)
+{
+       ofnode child;
+       struct udevice *child_dev;
+       int ret;
+
+       /* smd-edge subnode has no compatible, bind nop_parent manually */
+       child = ofnode_find_subnode(dev_ofnode(dev), "smd-edge");
+       if (ofnode_valid(child)) {
+               ret = device_bind_driver_to_node(dev, "nop_parent", "smd-edge", 
child, NULL);
+               if (ret)
+                       return ret;
+       }
+
+       dev_for_each_subnode(child, dev) {
+               ret = lists_bind_fdt(dev, child, &child_dev, NULL, false);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static const struct udevice_id rpm_proc_ids[] = {
+       { .compatible = "qcom,rpm-proc" },
+};
+
+U_BOOT_DRIVER(rpm_proc) = {
+       .name = "rpm_proc",
+       .id = UCLASS_NOP,
+       .of_match = rpm_proc_ids,
+       .bind = rpm_proc_bind,
+};
+
 static ulong stub_clk_set_rate(struct clk *clk, ulong rate)
 {
        return (clk->rate = rate);

-- 
2.55.0

Reply via email to