summaryrefslogtreecommitdiffstats
path: root/drivers/of/of_path.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/of_path.c')
-rw-r--r--drivers/of/of_path.c132
1 files changed, 38 insertions, 94 deletions
diff --git a/drivers/of/of_path.c b/drivers/of/of_path.c
index 6903905259..ed620f1755 100644
--- a/drivers/of/of_path.c
+++ b/drivers/of/of_path.c
@@ -23,16 +23,6 @@
#include <linux/mtd/mtd.h>
-struct of_path {
- struct cdev *cdev;
- struct device_d *dev;
-};
-
-struct of_path_type {
- const char *name;
- int (*parse)(struct of_path *op, const char *str);
-};
-
struct device_d *of_find_device_by_node_path(const char *path)
{
struct device_d *dev;
@@ -48,102 +38,44 @@ struct device_d *of_find_device_by_node_path(const char *path)
}
/**
- * of_path_type_partname - find a partition based on physical device and
- * partition name
- * @op: of_path context
- * @name: the partition name to find
+ * __of_find_path
+ *
+ * @node: The node to find the cdev for, can be the device or a
+ * partition in the device
+ * @part: Optionally, a description of a parition of @node. See of_find_path
+ * @outpath: if this function returns 0 outpath will contain the path belonging
+ * to the input path description. Must be freed with free().
+ * @flags: use OF_FIND_PATH_FLAGS_BB to return the .bb device if available
+ *
*/
-static int of_path_type_partname(struct of_path *op, const char *name)
-{
- if (!op->dev)
- return -EINVAL;
-
- op->cdev = device_find_partition(op->dev, name);
- if (op->cdev) {
- pr_debug("%s: found part '%s'\n", __func__, name);
- return 0;
- } else {
- pr_debug("%s: cannot find part '%s'\n", __func__, name);
- return -ENODEV;
- }
-}
-
-static struct of_path_type of_path_types[] = {
- {
- .name = "partname",
- .parse = of_path_type_partname,
- },
-};
-
-static int of_path_parse_one(struct of_path *op, const char *str)
+static int __of_find_path(struct device_node *node, const char *part, char **outpath, unsigned flags)
{
- int i, ret;
- char *name, *desc;
-
- pr_debug("parsing: %s\n", str);
-
- name = xstrdup(str);
- desc = strchr(name, ':');
- if (!desc) {
- free(name);
- return -EINVAL;
- }
-
- *desc = 0;
- desc++;
-
- for (i = 0; i < ARRAY_SIZE(of_path_types); i++) {
- if (!strcmp(of_path_types[i].name, name)) {
- ret = of_path_types[i].parse(op, desc);
- goto out;
- }
- }
-
- ret = -EINVAL;
-out:
- free(name);
-
- return ret;
-}
-
-static int __of_find_path(struct device_node *node, const char *propname, char **outpath, unsigned flags)
-{
- struct of_path op = {};
- const char *str;
+ struct device_d *dev;
+ struct cdev *cdev;
bool add_bb = false;
- int i, ret;
- op.dev = of_find_device_by_node_path(node->full_name);
- if (!op.dev) {
- op.dev = of_find_device_by_node_path(node->parent->full_name);
- if (!op.dev)
+ dev = of_find_device_by_node_path(node->full_name);
+ if (!dev) {
+ dev = of_find_device_by_node_path(node->parent->full_name);
+ if (!dev)
return -ENODEV;
}
- device_detect(op.dev);
-
- op.cdev = cdev_by_device_node(node);
+ device_detect(dev);
- i = 1;
+ if (part)
+ cdev = device_find_partition(dev, part);
+ else
+ cdev = cdev_by_device_node(node);
- while (propname) {
- ret = of_property_read_string_index(node, propname, i++, &str);
- if (ret)
- break;
-
- ret = of_path_parse_one(&op, str);
- if (ret)
- return ret;
- }
-
- if (!op.cdev)
+ if (!cdev)
return -ENOENT;
- if ((flags & OF_FIND_PATH_FLAGS_BB) && op.cdev->mtd &&
- mtd_can_have_bb(op.cdev->mtd))
+ if ((flags & OF_FIND_PATH_FLAGS_BB) && cdev->mtd &&
+ mtd_can_have_bb(cdev->mtd))
add_bb = true;
- *outpath = asprintf("/dev/%s%s", op.cdev->name, add_bb ? ".bb" : "");
+ *outpath = asprintf("/dev/%s%s", cdev->name, add_bb ? ".bb" : "");
return 0;
}
@@ -193,6 +125,8 @@ int of_find_path(struct device_node *node, const char *propname, char **outpath,
{
struct device_node *rnode;
const char *path;
+ const char *part = NULL;
+ const char partnamestr[] = "partname:";
path = of_get_property(node, propname, NULL);
if (!path)
@@ -202,5 +136,15 @@ int of_find_path(struct device_node *node, const char *propname, char **outpath,
if (!rnode)
return -ENODEV;
- return __of_find_path(rnode, propname, outpath, flags);
+ of_property_read_string_index(node, propname, 1, &part);
+ if (part) {
+ if (!strncmp(part, partnamestr, sizeof(partnamestr) - 1)) {
+ part += sizeof(partnamestr) - 1;
+ } else {
+ pr_err("Invalid device-path: %s\n", part);
+ return -EINVAL;
+ }
+ }
+
+ return __of_find_path(rnode, part, outpath, flags);
}