diff --git a/arch/arm/boards/highbank/init.c b/arch/arm/boards/highbank/init.c index 577ccc0..32e2173 100644 --- a/arch/arm/boards/highbank/init.c +++ b/arch/arm/boards/highbank/init.c @@ -37,14 +37,12 @@ if (!(reg & HB_PWRDOM_STAT_SATA)) { for_each_compatible_node_from(node, root, NULL, "calxeda,hb-ahci") - of_set_property(node, "status", "disabled", - sizeof("disabled"), 1); + of_property_write_string(node, "status", "disabled"); } if (!(reg & HB_PWRDOM_STAT_EMMC)) { for_each_compatible_node_from(node, root, NULL, "calxeda,hb-sdhci") - of_set_property(node, "status", "disabled", - sizeof("disabled"), 1); + of_property_write_string(node, "status", "disabled"); } if ((opp_table[0] >> 16) != HB_OPP_VERSION) diff --git a/arch/arm/cpu/psci.c b/arch/arm/cpu/psci.c index d650c23..eafb361 100644 --- a/arch/arm/cpu/psci.c +++ b/arch/arm/cpu/psci.c @@ -204,13 +204,11 @@ if (!psci) return -EINVAL; - ret = of_set_property(psci, "compatible", "arm,psci-1.0", - strlen("arm,psci-1.0") + 1, 1); + ret = of_property_write_string(psci, "compatible", "arm,psci-1.0"); if (ret) return ret; - ret = of_set_property(psci, "method", "smc", - strlen("smc") + 1, 1); + ret = of_property_write_string(psci, "method", "smc"); if (ret) return ret; diff --git a/arch/sandbox/board/hostfile.c b/arch/sandbox/board/hostfile.c index c1a2643..e7d92ea 100644 --- a/arch/sandbox/board/hostfile.c +++ b/arch/sandbox/board/hostfile.c @@ -133,8 +133,7 @@ node = of_new_node(root, hf->devname); - ret = of_set_property(node, "compatible", hostfile_dt_ids->compatible, - strlen(hostfile_dt_ids->compatible) + 1, 1); + ret = of_property_write_string(node, "compatible", hostfile_dt_ids->compatible); if (ret) return ret; @@ -146,8 +145,7 @@ if (ret) return ret; - ret = of_set_property(node, "barebox,filename", hf->filename, - strlen(hf->filename) + 1, 1); + ret = of_property_write_string(node, "barebox,filename", hf->filename); return ret; } diff --git a/common/memory.c b/common/memory.c index ad38b00..ff5bdc1 100644 --- a/common/memory.c +++ b/common/memory.c @@ -185,7 +185,7 @@ if (!memnode) return -ENOMEM; - err = of_set_property(memnode, "device_type", "memory", sizeof("memory"), 1); + err = of_property_write_string(memnode, "device_type", "memory"); if (err) return err; diff --git a/common/oftree.c b/common/oftree.c index e98b908..09a4455 100644 --- a/common/oftree.c +++ b/common/oftree.c @@ -128,7 +128,7 @@ return -ENOMEM; - err = of_set_property(node, "bootargs", str, strlen(str) + 1, 1); + err = of_property_write_string(node, "bootargs", str); return err; } diff --git a/common/partitions.c b/common/partitions.c index 69a2b1fe..574b31f 100644 --- a/common/partitions.c +++ b/common/partitions.c @@ -63,6 +63,8 @@ goto out; } + cdev->flags |= DEVFS_PARTITION_FROM_TABLE; + cdev->dos_partition_type = part->dos_partition_type; strcpy(cdev->partuuid, part->partuuid); diff --git a/common/state/state.c b/common/state/state.c index 4020d5e..02bb1bb 100644 --- a/common/state/state.c +++ b/common/state/state.c @@ -167,9 +167,8 @@ if ((conv == STATE_CONVERT_TO_NODE) || (conv == STATE_CONVERT_FIXUP)) { - ret = of_set_property(new_node, "type", - vtype->type_name, - strlen(vtype->type_name) + 1, 1); + ret = of_property_write_string(new_node, "type", + vtype->type_name); if (ret) goto out; diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 5867fe4..8326099 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -221,7 +221,7 @@ } list_for_each_entry_safe(cdev, ct, &old_dev->cdevs, devices_list) { - if (cdev->flags & DEVFS_IS_PARTITION) { + if (cdev->master) { dev_dbg(old_dev, "unregister part %s\n", cdev->name); devfs_del_partition(cdev->name); } diff --git a/drivers/eeprom/at24.c b/drivers/eeprom/at24.c index 4ae3776..1227286 100644 --- a/drivers/eeprom/at24.c +++ b/drivers/eeprom/at24.c @@ -500,6 +500,7 @@ goto err_devfs_create; of_parse_partitions(&at24->cdev, dev->device_node); + of_partitions_register_fixup(&at24->cdev); return 0; diff --git a/drivers/eeprom/at25.c b/drivers/eeprom/at25.c index f7f8368..1caaebd 100644 --- a/drivers/eeprom/at25.c +++ b/drivers/eeprom/at25.c @@ -360,6 +360,8 @@ dev_dbg(dev, "%s probed\n", at25->cdev.name); of_parse_partitions(&at25->cdev, dev->device_node); + of_partitions_register_fixup(&at25->cdev); + return 0; fail: diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c index 928277a..b173a17 100644 --- a/drivers/mci/mci-core.c +++ b/drivers/mci/mci-core.c @@ -1621,8 +1621,10 @@ rc = 0; /* it's not a failure */ } - if (np) + if (np) { of_parse_partitions(&part->blk.cdev, np); + of_partitions_register_fixup(&part->blk.cdev); + } return 0; } diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c index 4e7bfdb..1eb8dd3 100644 --- a/drivers/mtd/core.c +++ b/drivers/mtd/core.c @@ -556,67 +556,6 @@ return 0; } -static int of_mtd_fixup(struct device_node *root, void *ctx) -{ - struct mtd_info *mtd = ctx, *partmtd; - struct device_node *np, *part, *tmp; - int ret; - - np = of_find_node_by_path_from(root, mtd->of_path); - if (!np) { - dev_err(&mtd->class_dev, "Cannot find nodepath %s, cannot fixup\n", - mtd->of_path); - return -EINVAL; - } - - for_each_child_of_node_safe(np, tmp, part) { - if (of_get_property(part, "compatible", NULL)) - continue; - of_delete_node(part); - } - - list_for_each_entry(partmtd, &mtd->partitions, partitions_entry) { - int na, ns, len = 0; - char *name = basprintf("partition@%0llx", - partmtd->master_offset); - void *p; - u8 tmp[16 * 16]; /* Up to 64-bit address + 64-bit size */ - - if (!name) - return -ENOMEM; - - part = of_new_node(np, name); - free(name); - if (!part) - return -ENOMEM; - - p = of_new_property(part, "label", partmtd->cdev.partname, - strlen(partmtd->cdev.partname) + 1); - if (!p) - return -ENOMEM; - - na = of_n_addr_cells(part); - ns = of_n_size_cells(part); - - of_write_number(tmp + len, partmtd->master_offset, na); - len += na * 4; - of_write_number(tmp + len, partmtd->size, ns); - len += ns * 4; - - ret = of_set_property(part, "reg", tmp, len, 1); - if (ret) - return ret; - - if (partmtd->cdev.flags & DEVFS_PARTITION_READONLY) { - ret = of_set_property(part, "read-only", NULL, 0, 1); - if (ret) - return ret; - } - } - - return 0; -} - static int mtd_detect(struct device_d *dev) { struct mtd_info *mtd = container_of(dev, struct mtd_info, class_dev); @@ -732,7 +671,9 @@ of_parse_partitions(&mtd->cdev, mtd->parent->device_node); if (IS_ENABLED(CONFIG_OFDEVICE) && mtd->parent->device_node) { mtd->of_path = xstrdup(mtd->parent->device_node->full_name); - of_register_fixup(of_mtd_fixup, mtd); + ret = of_partitions_register_fixup(&mtd->cdev); + if (ret) + goto err1; } } diff --git a/drivers/mtd/partition.c b/drivers/mtd/partition.c index 777cb75..0136977 100644 --- a/drivers/mtd/partition.c +++ b/drivers/mtd/partition.c @@ -225,6 +225,8 @@ if (ret) goto err; + part->cdev.master = &part->master->cdev; + return part; err: free(part->cdev.partname); diff --git a/drivers/of/base.c b/drivers/of/base.c index bef8f1d..6632f4d 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1217,6 +1217,28 @@ } /** + * of_property_write_string - Write a string to a property. If + * the property does not exist, it will be created and appended to the given + * device node. + * + * @np: device node to which the property value is to be written. + * @propname: name of the property to be written. + * value: pointer to the string to write + * + * Search for a property in a device node and write a string to + * it. If the property does not exist, it will be created and appended to + * the device node. Returns 0 on success, -ENOMEM if the property or array + * of elements cannot be created. + */ +int of_property_write_string(struct device_node *np, + const char *propname, const char *value) +{ + size_t len = strlen(value); + + return of_set_property(np, propname, value, len + 1, 1); +} + +/** * of_parse_phandle_from - Resolve a phandle property to a device_node pointer from * a given root node * @np: Pointer to device node holding phandle property @@ -2093,7 +2115,7 @@ */ int of_device_disable(struct device_node *node) { - return of_set_property(node, "status", "disabled", sizeof("disabled"), 1); + return of_property_write_string(node, "status", "disabled"); } /** diff --git a/drivers/of/of_path.c b/drivers/of/of_path.c index e0b2dc1..a5886df 100644 --- a/drivers/of/of_path.c +++ b/drivers/of/of_path.c @@ -104,6 +104,113 @@ } /** + * of_find_node_by_devpath - translate a device path to a device tree node + * + * @root: The device tree root. Can be NULL, in this case the internal tree is used + * @path: The path to look the node up for. Can be "/dev/cdevname" or "cdevname" directly. + * + * This is the counterpart of of_find_path_by_node(). Given a path this function tries + * to find the corresponding node in the given device tree. + * + * We first have to find the hardware device in the tree we are passed and then find + * a partition matching offset/size in this tree. This is necessary because the + * passed tree may use another partition binding (legacy vs. fixed-partitions). Also + * the node names may differ (some device trees have partition@ instead of + * partition@. + */ +struct device_node *of_find_node_by_devpath(struct device_node *root, const char *path) +{ + struct cdev *cdev; + bool is_partition = false; + struct device_node *np, *partnode, *rnp; + loff_t part_offset = 0, part_size = 0; + + pr_debug("%s: looking for path %s\n", __func__, path); + + if (!strncmp(path, "/dev/", 5)) + path += 5; + + cdev = cdev_by_name(path); + if (!cdev) { + pr_debug("%s: cdev %s not found\n", __func__, path); + return NULL; + } + + /* + * Look for the device node of the master device (the one of_parse_partitions() has + * been called with + */ + if (cdev->master) { + is_partition = true; + part_offset = cdev->offset; + part_size = cdev->size; + pr_debug("%s path %s: is a partition with offset 0x%08llx, size 0x%08llx\n", + __func__, path, part_offset, part_size); + np = cdev->master->device_node; + } else { + np = cdev->device_node; + } + + /* + * Now find the device node of the master device in the device tree we have + * been passed. + */ + rnp = of_find_node_by_path_from(root, np->full_name); + if (!rnp) { + pr_debug("%s path %s: %s not found in passed tree\n", __func__, path, + np->full_name); + return NULL; + } + + if (!is_partition) { + pr_debug("%s path %s: returning full device node %s\n", __func__, path, + rnp->full_name); + return rnp; + } + + /* + * Look for a partition with matching offset/size in the device node of + * the tree we have been passed. + */ + partnode = of_get_child_by_name(rnp, "partitions"); + if (!partnode) { + pr_debug("%s path %s: using legacy partition binding\n", __func__, path); + partnode = rnp; + } + + for_each_child_of_node(partnode, np) { + const __be32 *reg; + int na, ns, len; + loff_t offset, size; + + reg = of_get_property(np, "reg", &len); + if (!reg) + return NULL; + + na = of_n_addr_cells(np); + ns = of_n_size_cells(np); + + if (len < (na + ns) * sizeof(__be32)) { + pr_err("reg property too small in %s\n", np->full_name); + continue; + } + + offset = of_read_number(reg, na); + size = of_read_number(reg + na, ns); + + if (part_offset == offset && part_size == size) { + pr_debug("%s path %s: found matching partition in %s\n", __func__, path, + np->full_name); + return np; + } + } + + pr_debug("%s path %s: no matching node found\n", __func__, path); + + return NULL; +} + +/** * of_find_path - translate a path description in the devicetree to a barebox * path * diff --git a/drivers/of/partition.c b/drivers/of/partition.c index 8c2aef2..25b41cb 100644 --- a/drivers/of/partition.c +++ b/drivers/of/partition.c @@ -23,6 +23,16 @@ #include #include #include +#include +#include + +static unsigned int of_partition_binding; + +enum of_binding_name { + MTD_OF_BINDING_NEW, + MTD_OF_BINDING_LEGACY, + MTD_OF_BINDING_DONTTOUCH, +}; struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node) { @@ -30,10 +40,11 @@ char *filename; struct cdev *new; const __be32 *reg; - unsigned long offset, size; + u64 offset, size; const char *name; int len; unsigned long flags = 0; + int na, ns; if (!node) return NULL; @@ -42,8 +53,16 @@ if (!reg) return NULL; - offset = be32_to_cpu(reg[0]); - size = be32_to_cpu(reg[1]); + na = of_n_addr_cells(node); + ns = of_n_size_cells(node); + + if (len < (na + ns) * sizeof(__be32)) { + pr_err("reg property too small in %s\n", node->full_name); + return NULL; + } + + offset = of_read_number(reg, na); + size = of_read_number(reg + na, ns); partname = of_get_property(node, "label", &len); if (!partname) @@ -53,7 +72,7 @@ name = (char *)partname; - debug("add partition: %s.%s 0x%08lx 0x%08lx\n", cdev->name, partname, offset, size); + debug("add partition: %s.%s 0x%08llx 0x%08llx\n", cdev->name, partname, offset, size); if (of_get_property(node, "read-only", &len)) flags = DEVFS_PARTITION_READONLY; @@ -79,6 +98,8 @@ if (!node) return -EINVAL; + cdev->device_node = node; + subnode = of_get_child_by_name(node, "partitions"); if (subnode) { if (!of_device_is_compatible(subnode, "fixed-partitions")) @@ -92,3 +113,150 @@ return 0; } + +static void delete_subnodes(struct device_node *np) +{ + struct device_node *part, *tmp; + + for_each_child_of_node_safe(np, tmp, part) { + if (of_get_property(part, "compatible", NULL)) + continue; + + of_delete_node(part); + } +} + +static int of_partition_fixup(struct device_node *root, void *ctx) +{ + struct cdev *cdev = ctx, *partcdev; + struct device_node *np, *part, *partnode; + int ret; + int n_cells, n_parts = 0; + + if (of_partition_binding == MTD_OF_BINDING_DONTTOUCH) + return 0; + + if (!cdev->device_node) + return -EINVAL; + + list_for_each_entry(partcdev, &cdev->partitions, partition_entry) { + if (partcdev->flags & DEVFS_PARTITION_FROM_TABLE) + continue; + n_parts++; + } + + if (!n_parts) + return 0; + + if (cdev->size >= 0x100000000) + n_cells = 2; + else + n_cells = 1; + + np = of_find_node_by_path_from(root, cdev->device_node->full_name); + if (!np) { + dev_err(cdev->dev, "Cannot find nodepath %s, cannot fixup\n", + cdev->device_node->full_name); + return -EINVAL; + } + + partnode = of_get_child_by_name(np, "partitions"); + if (partnode) { + if (of_partition_binding == MTD_OF_BINDING_LEGACY) { + of_delete_node(partnode); + partnode = np; + } + delete_subnodes(partnode); + } else { + delete_subnodes(np); + + if (of_partition_binding == MTD_OF_BINDING_LEGACY) + partnode = np; + else + partnode = of_new_node(np, "partitions"); + } + + if (of_partition_binding == MTD_OF_BINDING_NEW) { + ret = of_property_write_string(partnode, "compatible", + "fixed-partitions"); + if (ret) + return ret; + } + + of_property_write_u32(partnode, "#size-cells", n_cells); + if (ret) + return ret; + + of_property_write_u32(partnode, "#addres-cells", n_cells); + if (ret) + return ret; + + list_for_each_entry(partcdev, &cdev->partitions, partition_entry) { + int na, ns, len = 0; + char *name; + void *p; + u8 tmp[16 * 16]; /* Up to 64-bit address + 64-bit size */ + loff_t partoffset; + + if (partcdev->flags & DEVFS_PARTITION_FROM_TABLE) + continue; + + if (partcdev->mtd) + partoffset = partcdev->mtd->master_offset; + else + partoffset = partcdev->offset; + + name = basprintf("partition@%0llx", partoffset); + if (!name) + return -ENOMEM; + + part = of_new_node(partnode, name); + free(name); + if (!part) + return -ENOMEM; + + p = of_new_property(part, "label", partcdev->partname, + strlen(partcdev->partname) + 1); + if (!p) + return -ENOMEM; + + na = of_n_addr_cells(part); + ns = of_n_size_cells(part); + + of_write_number(tmp + len, partoffset, na); + len += na * 4; + of_write_number(tmp + len, partcdev->size, ns); + len += ns * 4; + + ret = of_set_property(part, "reg", tmp, len, 1); + if (ret) + return ret; + + if (partcdev->flags & DEVFS_PARTITION_READONLY) { + ret = of_set_property(part, "read-only", NULL, 0, 1); + if (ret) + return ret; + } + } + + return 0; +} + +int of_partitions_register_fixup(struct cdev *cdev) +{ + return of_register_fixup(of_partition_fixup, cdev); +} + +static const char *of_binding_names[] = { + "new", "legacy", "donttouch" +}; + +static int of_partition_init(void) +{ + dev_add_param_enum(&global_device, "of_partition_binding", NULL, NULL, + &of_partition_binding, of_binding_names, + ARRAY_SIZE(of_binding_names), NULL); + + return 0; +} +device_initcall(of_partition_init); diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c index 3572629..a2c59de 100644 --- a/drivers/video/simplefb.c +++ b/drivers/video/simplefb.c @@ -89,9 +89,6 @@ static int simplefb_create_node(struct device_node *root, const struct fb_info *fbi, const char *format) { - const char *compat = "simple-framebuffer"; - const char *disabled = "disabled"; - const char *okay = "okay"; struct device_node *node; u32 cells[2]; int ret; @@ -100,12 +97,11 @@ if (!node) return -ENOMEM; - ret = of_set_property(node, "status", disabled, - strlen(disabled) + 1, 1); + ret = of_property_write_string(node, "status", "disabled"); if (ret < 0) return ret; - ret = of_set_property(node, "compatible", compat, strlen(compat) + 1, 1); + ret = of_property_write_string(node, "compatible", "simple-framebuffer"); if (ret) return ret; @@ -130,14 +126,14 @@ if (ret < 0) return ret; - ret = of_set_property(node, "format", format, strlen(format) + 1, 1); + ret = of_property_write_string(node, "format", format); if (ret < 0) return ret; of_add_reserve_entry((u32)fbi->screen_base, (u32)fbi->screen_base + fbi->screen_size); - return of_set_property(node, "status", okay, strlen(okay) + 1, 1); + return of_property_write_string(node, "status", "okay"); } static int simplefb_of_fixup(struct device_node *root, void *ctx) diff --git a/fs/devfs-core.c b/fs/devfs-core.c index 75ed3b0..382606f 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -37,7 +37,7 @@ len = strlen(instr); list_for_each_entry(cdev, &cdev_list, list) { - if (cdev->flags & DEVFS_IS_PARTITION && + if (cdev->master && !strncmp(instr, cdev->name, len)) { string_list_add_asprintf(sl, "%s ", cdev->name); } @@ -184,76 +184,8 @@ return cdev->ops->flush(cdev); } -static int partition_ioctl(struct cdev *cdev, int request, void *buf) -{ - int ret = 0; - loff_t offset, *_buf = buf; - struct mtd_info_user *user = buf; - - switch (request) { - case MEMSETBADBLOCK: - case MEMSETGOODBLOCK: - case MEMGETBADBLOCK: - offset = *_buf; - offset += cdev->offset; - ret = cdev->ops->ioctl(cdev, request, &offset); - break; - case MEMGETINFO: - if (cdev->mtd) { - user->type = cdev->mtd->type; - user->flags = cdev->mtd->flags; - user->size = cdev->mtd->size; - user->erasesize = cdev->mtd->erasesize; - user->writesize = cdev->mtd->writesize; - user->oobsize = cdev->mtd->oobsize; - user->subpagesize = cdev->mtd->writesize >> cdev->mtd->subpage_sft; - user->mtd = cdev->mtd; - /* The below fields are obsolete */ - user->ecctype = -1; - user->eccsize = 0; - break; - } - if (!cdev->ops->ioctl) { - ret = -EINVAL; - break; - } - ret = cdev->ops->ioctl(cdev, request, buf); - break; -#if (defined(CONFIG_NAND_ECC_HW) || defined(CONFIG_NAND_ECC_SOFT)) - case ECCGETSTATS: -#endif - case MEMERASE: - if (!cdev->ops->ioctl) { - ret = -EINVAL; - break; - } - ret = cdev->ops->ioctl(cdev, request, buf); - break; -#ifdef CONFIG_PARTITION - case MEMGETREGIONINFO: - if (cdev->mtd) { - struct region_info_user *reg = buf; - int erasesize_shift = ffs(cdev->mtd->erasesize) - 1; - - reg->offset = cdev->offset; - reg->erasesize = cdev->mtd->erasesize; - reg->numblocks = cdev->size >> erasesize_shift; - reg->regionindex = cdev->mtd->index; - } - break; -#endif - default: - ret = -EINVAL; - } - - return ret; -} - int cdev_ioctl(struct cdev *cdev, int request, void *buf) { - if (cdev->flags & DEVFS_IS_PARTITION) - return partition_ioctl(cdev, request, buf); - if (!cdev->ops->ioctl) return -EINVAL; @@ -277,6 +209,7 @@ return -EEXIST; INIT_LIST_HEAD(&new->links); + INIT_LIST_HEAD(&new->partitions); list_add_tail(&new->list, &cdev_list); if (new->dev) { @@ -326,6 +259,9 @@ list_for_each_entry_safe(c, tmp, &cdev->links, link_entry) devfs_remove(c); + if (cdev->master) + list_del(&cdev->partition_entry); + if (cdev->link) free(cdev); @@ -374,6 +310,8 @@ partinfo->flags, partinfo->name); if (IS_ERR(mtd)) return (void *)mtd; + + list_add_tail(&mtd->cdev.partition_entry, &cdev->partitions); return &mtd->cdev; } @@ -388,7 +326,9 @@ new->offset = cdev->offset + offset; new->dev = cdev->dev; - new->flags = partinfo->flags | DEVFS_IS_PARTITION; + new->master = cdev; + + list_add_tail(&new->partition_entry, &cdev->partitions); devfs_create(new); @@ -428,7 +368,7 @@ return ret; } - if (!(cdev->flags & DEVFS_IS_PARTITION)) + if (!cdev->master) return -EINVAL; if (cdev->flags & DEVFS_PARTITION_FIXED) return -EPERM; diff --git a/include/driver.h b/include/driver.h index 6abaaad..52e06f7 100644 --- a/include/driver.h +++ b/include/driver.h @@ -459,6 +459,8 @@ u8 dos_partition_type; struct cdev *link; struct list_head link_entry, links; + struct list_head partition_entry, partitions; + struct cdev *master; }; int devfs_create(struct cdev *); @@ -481,8 +483,8 @@ #define DEVFS_PARTITION_FIXED (1U << 0) #define DEVFS_PARTITION_READONLY (1U << 1) -#define DEVFS_IS_PARTITION (1 << 2) #define DEVFS_IS_CHARACTER_DEV (1 << 3) +#define DEVFS_PARTITION_FROM_TABLE (1 << 4) struct cdev *devfs_add_partition(const char *devname, loff_t offset, loff_t size, unsigned int flags, const char *name); diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index f93fac0..fa35c7e 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -228,6 +228,7 @@ struct list_head partitions_entry; char *of_path; + unsigned int of_binding; }; int mtd_erase(struct mtd_info *mtd, struct erase_info *instr); diff --git a/include/of.h b/include/of.h index e3bb452..0ba73f1 100644 --- a/include/of.h +++ b/include/of.h @@ -205,6 +205,8 @@ extern int of_property_write_u64_array(struct device_node *np, const char *propname, const u64 *values, size_t sz); +extern int of_property_write_string(struct device_node *np, const char *propname, + const char *value); extern struct device_node *of_parse_phandle(const struct device_node *np, const char *phandle_name, @@ -238,6 +240,7 @@ struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node); int of_parse_partitions(struct cdev *cdev, struct device_node *node); +int of_partitions_register_fixup(struct cdev *cdev); int of_device_is_stdout_path(struct device_d *dev); const char *of_get_model(void); void *of_flatten_dtb(struct device_node *node); @@ -248,6 +251,7 @@ #define OF_FIND_PATH_FLAGS_BB 1 /* return .bb device if available */ int of_find_path(struct device_node *node, const char *propname, char **outpath, unsigned flags); int of_find_path_by_node(struct device_node *node, char **outpath, unsigned flags); +struct device_node *of_find_node_by_devpath(struct device_node *root, const char *path); int of_register_fixup(int (*fixup)(struct device_node *, void *), void *context); int of_unregister_fixup(int (*fixup)(struct device_node *, void *), void *context); int of_register_set_status_fixup(const char *node, bool status); @@ -262,6 +266,11 @@ return -EINVAL; } +static inline int of_partitions_register_fixup(struct cdev *cdev) +{ + return -ENOSYS; +} + static inline int of_device_is_stdout_path(struct device_d *dev) { return 0; @@ -466,6 +475,12 @@ return -ENOSYS; } +static inline int of_property_write_string(struct device_node *np, const char *propname, + const char *value) +{ + return -ENOSYS; +} + static inline struct device_node *of_parse_phandle(const struct device_node *np, const char *phandle_name, int index) {