Merge tag 'iommu-updates-v6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/joro...
[linux-2.6-microblaze.git] / drivers / of / device.c
index 873d933..de89f99 100644 (file)
@@ -312,3 +312,44 @@ int of_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env *
        return 0;
 }
 EXPORT_SYMBOL_GPL(of_device_uevent_modalias);
+
+/**
+ * of_device_make_bus_id - Use the device node data to assign a unique name
+ * @dev: pointer to device structure that is linked to a device tree node
+ *
+ * This routine will first try using the translated bus address to
+ * derive a unique name. If it cannot, then it will prepend names from
+ * parent nodes until a unique name can be derived.
+ */
+void of_device_make_bus_id(struct device *dev)
+{
+       struct device_node *node = dev->of_node;
+       const __be32 *reg;
+       u64 addr;
+       u32 mask;
+
+       /* Construct the name, using parent nodes if necessary to ensure uniqueness */
+       while (node->parent) {
+               /*
+                * If the address can be translated, then that is as much
+                * uniqueness as we need. Make it the first component and return
+                */
+               reg = of_get_property(node, "reg", NULL);
+               if (reg && (addr = of_translate_address(node, reg)) != OF_BAD_ADDR) {
+                       if (!of_property_read_u32(node, "mask", &mask))
+                               dev_set_name(dev, dev_name(dev) ? "%llx.%x.%pOFn:%s" : "%llx.%x.%pOFn",
+                                            addr, ffs(mask) - 1, node, dev_name(dev));
+
+                       else
+                               dev_set_name(dev, dev_name(dev) ? "%llx.%pOFn:%s" : "%llx.%pOFn",
+                                            addr, node, dev_name(dev));
+                       return;
+               }
+
+               /* format arguments only used if dev_name() resolves to NULL */
+               dev_set_name(dev, dev_name(dev) ? "%s:%s" : "%s",
+                            kbasename(node->full_name), dev_name(dev));
+               node = node->parent;
+       }
+}
+EXPORT_SYMBOL_GPL(of_device_make_bus_id);