diff options
Diffstat (limited to 'drivers/of/of_path.c')
-rw-r--r-- | drivers/of/of_path.c | 113 |
1 files changed, 66 insertions, 47 deletions
diff --git a/drivers/of/of_path.c b/drivers/of/of_path.c index 5c3a020345..42efb1ad1d 100644 --- a/drivers/of/of_path.c +++ b/drivers/of/of_path.c @@ -1,20 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * of_path.c * * Copyright (c) 2013 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <common.h> @@ -24,14 +12,14 @@ #include <linux/mtd/mtd.h> -struct device_d *of_find_device_by_node_path(const char *path) +struct device *of_find_device_by_node_path(const char *path) { - struct device_d *dev; + struct device *dev; for_each_device(dev) { - if (!dev->device_node) + if (!dev->of_node) continue; - if (!strcmp(path, dev->device_node->full_name)) + if (!strcmp(path, dev->of_node->full_name)) return dev; } @@ -39,21 +27,27 @@ struct device_d *of_find_device_by_node_path(const char *path) } /** - * __of_find_path + * __of_cdev_find * * @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 + * @part: Optionally, a description of a partition of @node. See of_find_path * */ -static int __of_find_path(struct device_node *node, const char *part, char **outpath, unsigned flags) +static struct cdev *__of_cdev_find(struct device_node *node, const char *part) { - struct device_d *dev; + struct device *dev; struct cdev *cdev; - bool add_bb = false; + + /* + * On EFI, where devices are not instantiated from device tree, the + * state backend may point at a top-level fixed-partitions partition + * subnode with a partuuid property, which will be looked up globally. + * + * In order to support this binding, we do not early exit when + * of_partition_ensure_probed fails, but instead try the custom binding. + */ + (void)of_partition_ensure_probed(node); dev = of_find_device_by_node_path(node->full_name); if (!dev) { @@ -66,24 +60,17 @@ static int __of_find_path(struct device_node *node, const char *part, char **out /* when partuuid is specified short-circuit the search for the cdev */ ret = of_property_read_string(node, "partuuid", &uuid); - if (!ret) { - cdev = cdev_by_partuuid(uuid); - if (!cdev) - return -ENODEV; - - *outpath = basprintf("/dev/%s", cdev->name); - - return 0; - } + if (!ret) + return cdev_by_partuuid(uuid) ?: ERR_PTR(-ENODEV); } dev = of_find_device_by_node_path(devnode->full_name); if (!dev) - return -ENODEV; + return ERR_PTR(-ENODEV); } if (dev->bus && !dev->driver) - return -EPROBE_DEFER; + return ERR_PTR(-EPROBE_DEFER); device_detect(dev); @@ -92,8 +79,40 @@ static int __of_find_path(struct device_node *node, const char *part, char **out else cdev = cdev_by_device_node(node); - if (!cdev) - return -ENOENT; + return cdev ?: ERR_PTR(-ENOENT); +} + +/** + * of_cdev_find + * + * @node: The node to find the cdev for, can be the device or a + * partition in the device + * + */ +struct cdev *of_cdev_find(struct device_node *node) +{ + return __of_cdev_find(node, NULL); +} + +/** + * __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 partition 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_find_path(struct device_node *node, const char *part, char **outpath, unsigned flags) +{ + bool add_bb = false; + struct cdev *cdev; + + cdev = __of_cdev_find(node, part); + if (IS_ERR(cdev)) + return PTR_ERR(cdev); if ((flags & OF_FIND_PATH_FLAGS_BB) && cdev->mtd && mtd_can_have_bb(cdev->mtd)) @@ -162,9 +181,9 @@ struct device_node *of_find_node_by_devpath(struct device_node *root, const char 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; + np = cdev_of_node(cdev->master); } else { - np = cdev->device_node; + np = cdev_of_node(cdev); } /* @@ -173,14 +192,14 @@ struct device_node *of_find_node_by_devpath(struct device_node *root, const char */ 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); + pr_debug("%s path %s: %pOF not found in passed tree\n", __func__, path, + np); return NULL; } if (!is_partition) { - pr_debug("%s path %s: returning full device node %s\n", __func__, path, - rnp->full_name); + pr_debug("%s path %s: returning full device node %pOF\n", __func__, path, + rnp); return rnp; } @@ -207,7 +226,7 @@ struct device_node *of_find_node_by_devpath(struct device_node *root, const char ns = of_n_size_cells(np); if (len < (na + ns) * sizeof(__be32)) { - pr_err("reg property too small in %s\n", np->full_name); + pr_err("reg property too small in %pOF\n", np); continue; } @@ -215,8 +234,8 @@ struct device_node *of_find_node_by_devpath(struct device_node *root, const char 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); + pr_debug("%s path %s: found matching partition in %pOF\n", __func__, path, + np); return np; } } |