summaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/base.c58
-rw-r--r--drivers/of/fdt.c14
-rw-r--r--drivers/of/of_mdio.c8
-rw-r--r--drivers/of/platform.c7
-rw-r--r--drivers/of/unittest.c4
5 files changed, 68 insertions, 23 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 55e7f5bb0549..1d667eb730e1 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1286,6 +1286,13 @@ int of_phandle_iterator_init(struct of_phandle_iterator *it,
memset(it, 0, sizeof(*it));
+ /*
+ * one of cell_count or cells_name must be provided to determine the
+ * argument length.
+ */
+ if (cell_count < 0 && !cells_name)
+ return -EINVAL;
+
list = of_get_property(np, list_name, &size);
if (!list)
return -ENOENT;
@@ -1335,11 +1342,20 @@ int of_phandle_iterator_next(struct of_phandle_iterator *it)
if (of_property_read_u32(it->node, it->cells_name,
&count)) {
- pr_err("%pOF: could not get %s for %pOF\n",
- it->parent,
- it->cells_name,
- it->node);
- goto err;
+ /*
+ * If both cell_count and cells_name is given,
+ * fall back to cell_count in absence
+ * of the cells_name property
+ */
+ if (it->cell_count >= 0) {
+ count = it->cell_count;
+ } else {
+ pr_err("%pOF: could not get %s for %pOF\n",
+ it->parent,
+ it->cells_name,
+ it->node);
+ goto err;
+ }
}
} else {
count = it->cell_count;
@@ -1503,10 +1519,17 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
const char *cells_name, int index,
struct of_phandle_args *out_args)
{
+ int cell_count = -1;
+
if (index < 0)
return -EINVAL;
- return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
- index, out_args);
+
+ /* If cells_name is NULL we assume a cell count of 0 */
+ if (!cells_name)
+ cell_count = 0;
+
+ return __of_parse_phandle_with_args(np, list_name, cells_name,
+ cell_count, index, out_args);
}
EXPORT_SYMBOL(of_parse_phandle_with_args);
@@ -1588,7 +1611,7 @@ int of_parse_phandle_with_args_map(const struct device_node *np,
if (!pass_name)
goto free;
- ret = __of_parse_phandle_with_args(np, list_name, cells_name, 0, index,
+ ret = __of_parse_phandle_with_args(np, list_name, cells_name, -1, index,
out_args);
if (ret)
goto free;
@@ -1756,7 +1779,24 @@ int of_count_phandle_with_args(const struct device_node *np, const char *list_na
struct of_phandle_iterator it;
int rc, cur_index = 0;
- rc = of_phandle_iterator_init(&it, np, list_name, cells_name, 0);
+ /*
+ * If cells_name is NULL we assume a cell count of 0. This makes
+ * counting the phandles trivial as each 32bit word in the list is a
+ * phandle and no arguments are to consider. So we don't iterate through
+ * the list but just use the length to determine the phandle count.
+ */
+ if (!cells_name) {
+ const __be32 *list;
+ int size;
+
+ list = of_get_property(np, list_name, &size);
+ if (!list)
+ return -ENOENT;
+
+ return size / sizeof(*list);
+ }
+
+ rc = of_phandle_iterator_init(&it, np, list_name, cells_name, -1);
if (rc)
return rc;
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 9cdf14b9aaab..223d617ecfe1 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -24,6 +24,7 @@
#include <linux/debugfs.h>
#include <linux/serial_core.h>
#include <linux/sysfs.h>
+#include <linux/random.h>
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
#include <asm/page.h>
@@ -1044,6 +1045,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
{
int l;
const char *p;
+ const void *rng_seed;
pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
@@ -1078,6 +1080,18 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
pr_debug("Command line is: %s\n", (char*)data);
+ rng_seed = of_get_flat_dt_prop(node, "rng-seed", &l);
+ if (rng_seed && l > 0) {
+ add_bootloader_randomness(rng_seed, l);
+
+ /* try to clear seed so it won't be found. */
+ fdt_nop_property(initial_boot_params, node, "rng-seed");
+
+ /* update CRC check value */
+ of_fdt_crc32 = crc32_be(~0, initial_boot_params,
+ fdt_totalsize(initial_boot_params));
+ }
+
/* break now */
return 1;
}
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 44f53496cab1..000b95787df1 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -280,12 +280,6 @@ unregister:
}
EXPORT_SYMBOL(of_mdiobus_register);
-/* Helper function for of_phy_find_device */
-static int of_phy_match(struct device *dev, const void *phy_np)
-{
- return dev->of_node == phy_np;
-}
-
/**
* of_phy_find_device - Give a PHY node, find the phy_device
* @phy_np: Pointer to the phy's device tree node
@@ -301,7 +295,7 @@ struct phy_device *of_phy_find_device(struct device_node *phy_np)
if (!phy_np)
return NULL;
- d = bus_find_device(&mdio_bus_type, NULL, phy_np, of_phy_match);
+ d = bus_find_device_by_of_node(&mdio_bus_type, phy_np);
if (d) {
mdiodev = to_mdio_device(d);
if (mdiodev->flags & MDIO_DEVICE_FLAG_PHY)
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 7801e25e6895..b47a2292fe8e 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -37,11 +37,6 @@ static const struct of_device_id of_skipped_node_table[] = {
{} /* Empty terminated list */
};
-static int of_dev_node_match(struct device *dev, const void *data)
-{
- return dev->of_node == data;
-}
-
/**
* of_find_device_by_node - Find the platform_device associated with a node
* @np: Pointer to device tree node
@@ -55,7 +50,7 @@ struct platform_device *of_find_device_by_node(struct device_node *np)
{
struct device *dev;
- dev = bus_find_device(&platform_bus_type, NULL, np, of_dev_node_match);
+ dev = bus_find_device_by_of_node(&platform_bus_type, np);
return dev ? to_platform_device(dev) : NULL;
}
EXPORT_SYMBOL(of_find_device_by_node);
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index e6b175370f2e..480a21e2ed39 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -1044,8 +1044,10 @@ static void __init of_unittest_platform_populate(void)
test_bus = platform_device_register_full(&test_bus_info);
rc = PTR_ERR_OR_ZERO(test_bus);
unittest(!rc, "testbus registration failed; rc=%i\n", rc);
- if (rc)
+ if (rc) {
+ of_node_put(np);
return;
+ }
test_bus->dev.of_node = np;
/*
OpenPOWER on IntegriCloud