Merge tag 'iomap-6.0-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
[linux-2.6-microblaze.git] / drivers / mtd / mtdcore.c
index 9eb0680..a9b8be9 100644 (file)
@@ -546,6 +546,68 @@ static int mtd_nvmem_add(struct mtd_info *mtd)
        return 0;
 }
 
+static void mtd_check_of_node(struct mtd_info *mtd)
+{
+       struct device_node *partitions, *parent_dn, *mtd_dn = NULL;
+       const char *pname, *prefix = "partition-";
+       int plen, mtd_name_len, offset, prefix_len;
+       struct mtd_info *parent;
+       bool found = false;
+
+       /* Check if MTD already has a device node */
+       if (dev_of_node(&mtd->dev))
+               return;
+
+       /* Check if a partitions node exist */
+       if (!mtd_is_partition(mtd))
+               return;
+       parent = mtd->parent;
+       parent_dn = dev_of_node(&parent->dev);
+       if (!parent_dn)
+               return;
+
+       partitions = of_get_child_by_name(parent_dn, "partitions");
+       if (!partitions)
+               goto exit_parent;
+
+       prefix_len = strlen(prefix);
+       mtd_name_len = strlen(mtd->name);
+
+       /* Search if a partition is defined with the same name */
+       for_each_child_of_node(partitions, mtd_dn) {
+               offset = 0;
+
+               /* Skip partition with no/wrong prefix */
+               if (!of_node_name_prefix(mtd_dn, "partition-"))
+                       continue;
+
+               /* Label have priority. Check that first */
+               if (of_property_read_string(mtd_dn, "label", &pname)) {
+                       of_property_read_string(mtd_dn, "name", &pname);
+                       offset = prefix_len;
+               }
+
+               plen = strlen(pname) - offset;
+               if (plen == mtd_name_len &&
+                   !strncmp(mtd->name, pname + offset, plen)) {
+                       found = true;
+                       break;
+               }
+       }
+
+       if (!found)
+               goto exit_partitions;
+
+       /* Set of_node only for nvmem */
+       if (of_device_is_compatible(mtd_dn, "nvmem-cells"))
+               mtd_set_of_node(mtd, mtd_dn);
+
+exit_partitions:
+       of_node_put(partitions);
+exit_parent:
+       of_node_put(parent_dn);
+}
+
 /**
  *     add_mtd_device - register an MTD device
  *     @mtd: pointer to new MTD device info structure
@@ -658,6 +720,7 @@ int add_mtd_device(struct mtd_info *mtd)
        mtd->dev.devt = MTD_DEVT(i);
        dev_set_name(&mtd->dev, "mtd%d", i);
        dev_set_drvdata(&mtd->dev, mtd);
+       mtd_check_of_node(mtd);
        of_node_get(mtd_get_of_node(mtd));
        error = device_register(&mtd->dev);
        if (error)