dm: Use driver_info index instead of pointer
At present we use a 'node' pointer in the of-platadata phandle_n_arg
structs. This is a pointer to the struct driver_info for a particular
device, and we can use it to obtain the struct udevice pointer itself.
Since we don't know the struct udevice pointer until it is allocated in
memory, we have to fix up the phandle_n_arg.node at runtime. This is
annoying since it requires that SPL's data is writable and adds a small
amount of extra (generated) code in the dm_populate_phandle_data()
function.
Now that we can find a driver_info by its index, it is easier to put the
index in the phandle_n_arg structures.
Update dtoc to do this, add a new device_get_by_driver_info_idx() to look
up a device by drive_info index and update the tests to match.
Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 31c5997..ac954a3 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -38,8 +38,7 @@
{
int ret;
- ret = device_get_by_driver_info((struct driver_info *)cells->node,
- &clk->dev);
+ ret = device_get_by_driver_info_idx(cells->idx, &clk->dev);
if (ret)
return ret;
clk->id = cells->arg[0];
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 2e5767e..4b3dcb3 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -772,6 +772,17 @@
return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
}
+
+int device_get_by_driver_info_idx(uint idx, struct udevice **devp)
+{
+ struct driver_rt *drt = gd_dm_driver_rt() + idx;
+ struct udevice *dev;
+
+ dev = drt->dev;
+ *devp = NULL;
+
+ return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
+}
#endif
int device_find_first_child(const struct udevice *parent, struct udevice **devp)
diff --git a/drivers/misc/irq-uclass.c b/drivers/misc/irq-uclass.c
index 94fa233..24b2796 100644
--- a/drivers/misc/irq-uclass.c
+++ b/drivers/misc/irq-uclass.c
@@ -69,7 +69,7 @@
{
int ret;
- ret = device_get_by_driver_info(cells->node, &irq->dev);
+ ret = device_get_by_driver_info_idx(cells->idx, &irq->dev);
if (ret)
return ret;
irq->id = cells->arg[0];
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 1c015ab..22040c6 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -1504,12 +1504,9 @@
if (CONFIG_IS_ENABLED(DM_GPIO) && !priv->non_removable) {
struct udevice *gpiodev;
- struct driver_info *info;
-
- info = (struct driver_info *)dtplat->cd_gpios->node;
-
- ret = device_get_by_driver_info(info, &gpiodev);
+ ret = device_get_by_driver_info_idx(dtplat->cd_gpios->idx,
+ &gpiodev);
if (ret)
return ret;
diff --git a/include/dm/device.h b/include/dm/device.h
index 993c9e6..5bef484 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -554,6 +554,20 @@
struct udevice **devp);
/**
+ * device_get_by_driver_info_idx() - Get a device based on driver_info index
+ *
+ * Locates a device by its struct driver_info, by using its index number which
+ * is written into the idx field of struct phandle_1_arg, etc.
+ *
+ * The device is probed to activate it ready for use.
+ *
+ * @idx: Index number of the driver_info structure (0=first)
+ * @devp: Returns pointer to device if found, otherwise this is set to NULL
+ * @return 0 if OK, -ve on error
+ */
+int device_get_by_driver_info_idx(uint idx, struct udevice **devp);
+
+/**
* device_find_first_child() - Find the first child of a device
*
* @parent: Parent device to search
diff --git a/include/dt-structs.h b/include/dt-structs.h
index eed8273..f0e1c9c 100644
--- a/include/dt-structs.h
+++ b/include/dt-structs.h
@@ -11,17 +11,17 @@
struct driver_info;
struct phandle_0_arg {
- const struct driver_info *node;
+ uint idx;
int arg[0];
};
struct phandle_1_arg {
- const struct driver_info *node;
+ uint idx;
int arg[1];
};
struct phandle_2_arg {
- const struct driver_info *node;
+ uint idx;
int arg[2];
};
#include <generated/dt-structs-gen.h>
diff --git a/test/dm/of_platdata.c b/test/dm/of_platdata.c
index bad733f..4f3cc15 100644
--- a/test/dm/of_platdata.c
+++ b/test/dm/of_platdata.c
@@ -183,22 +183,22 @@
ut_asserteq_str("sandbox_clk_test", dev->name);
plat = dev_get_platdata(dev);
- ut_assertok(device_get_by_driver_info(plat->clocks[0].node, &clk));
+ ut_assertok(device_get_by_driver_info_idx(plat->clocks[0].idx, &clk));
ut_asserteq_str("fixed_clock", clk->name);
- ut_assertok(device_get_by_driver_info(plat->clocks[1].node, &clk));
+ ut_assertok(device_get_by_driver_info_idx(plat->clocks[1].idx, &clk));
ut_asserteq_str("sandbox_clk", clk->name);
ut_asserteq(1, plat->clocks[1].arg[0]);
- ut_assertok(device_get_by_driver_info(plat->clocks[2].node, &clk));
+ ut_assertok(device_get_by_driver_info_idx(plat->clocks[2].idx, &clk));
ut_asserteq_str("sandbox_clk", clk->name);
ut_asserteq(0, plat->clocks[2].arg[0]);
- ut_assertok(device_get_by_driver_info(plat->clocks[3].node, &clk));
+ ut_assertok(device_get_by_driver_info_idx(plat->clocks[3].idx, &clk));
ut_asserteq_str("sandbox_clk", clk->name);
ut_asserteq(3, plat->clocks[3].arg[0]);
- ut_assertok(device_get_by_driver_info(plat->clocks[4].node, &clk));
+ ut_assertok(device_get_by_driver_info_idx(plat->clocks[4].idx, &clk));
ut_asserteq_str("sandbox_clk", clk->name);
ut_asserteq(2, plat->clocks[4].arg[0]);
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index 9d22df8..fd24635 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -127,6 +127,24 @@
return !strstr(fname, "video") || strstr(test->name, "video_base");
}
+static bool test_matches(const char *test_name, const char *find_name)
+{
+ if (!find_name)
+ return true;
+
+ if (!strcmp(test_name, find_name))
+ return true;
+
+ /* All tests have this prefix */
+ if (!strncmp(test_name, "dm_test_", 8))
+ test_name += 8;
+
+ if (!strcmp(test_name, find_name))
+ return true;
+
+ return false;
+}
+
int dm_test_main(const char *test_name)
{
struct unit_test *tests = ll_entry_start(struct unit_test, dm_test);
@@ -152,6 +170,7 @@
if (!test_name)
printf("Running %d driver model tests\n", n_ents);
+ else
found = 0;
uts->of_root = gd_of_root();
@@ -159,10 +178,7 @@
const char *name = test->name;
int runs;
- /* All tests have this prefix */
- if (!strncmp(name, "dm_test_", 8))
- name += 8;
- if (test_name && strcmp(test_name, name))
+ if (!test_matches(name, test_name))
continue;
/* Run with the live tree if possible */
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 8832e6e..2be11ff 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -154,8 +154,6 @@
key: Driver alias declared with
U_BOOT_DRIVER_ALIAS(driver_alias, driver_name)
value: Driver name declared with U_BOOT_DRIVER(driver_name)
- _links: List of links to be included in dm_populate_phandle_data(),
- each a PhandleLink
_drivers_additional: List of additional drivers to use during scanning
"""
def __init__(self, dtb_fname, include_disabled, warning_disabled,
@@ -169,7 +167,6 @@
self._lines = []
self._drivers = []
self._driver_aliases = {}
- self._links = []
self._drivers_additional = drivers_additional
def get_normalized_compat_name(self, node):
@@ -612,17 +609,11 @@
name = conv_name_to_c(target_node.name)
arg_values = []
for i in range(args):
- arg_values.append(str(fdt_util.fdt32_to_cpu(prop.value[pos + 1 + i])))
+ arg_values.append(
+ str(fdt_util.fdt32_to_cpu(prop.value[pos + 1 + i])))
pos += 1 + args
- # node member is filled with NULL as the real value
- # will be update at run-time during dm_init_and_scan()
- # by dm_populate_phandle_data()
- vals.append('\t{NULL, {%s}}' % (', '.join(arg_values)))
- var_node = '%s%s.%s[%d].node' % \
- (VAL_PREFIX, var_name, member_name, item)
- # Save the the link information to be use to define
- # dm_populate_phandle_data()
- self._links.append(PhandleLink(var_node, name))
+ vals.append('\t{%d, {%s}}' % (target_node.idx,
+ ', '.join(arg_values)))
item += 1
for val in vals:
self.buf('\n\t\t%s,' % val)
@@ -703,9 +694,6 @@
# nodes using DM_GET_DEVICE
# dtv_dmc_at_xxx.clocks[0].node = DM_GET_DEVICE(clock_controller_at_xxx)
self.buf('void dm_populate_phandle_data(void) {\n')
- for link in self._links:
- self.buf('\t%s = DM_GET_DEVICE(%s);\n' %
- (link.var_node, link.dev_name))
self.buf('}\n')
self.out(''.join(self.get_buf()))
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index fee9853..8e16dc0 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -419,10 +419,10 @@
/* Node /phandle-source index 2 */
static struct dtd_source dtv_phandle_source = {
\t.clocks\t\t\t= {
-\t\t\t{NULL, {}},
-\t\t\t{NULL, {11}},
-\t\t\t{NULL, {12, 13}},
-\t\t\t{NULL, {}},},
+\t\t\t{4, {}},
+\t\t\t{0, {11}},
+\t\t\t{1, {12, 13}},
+\t\t\t{4, {}},},
};
U_BOOT_DEVICE(phandle_source) = {
\t.name\t\t= "source",
@@ -434,7 +434,7 @@
/* Node /phandle-source2 index 3 */
static struct dtd_source dtv_phandle_source2 = {
\t.clocks\t\t\t= {
-\t\t\t{NULL, {}},},
+\t\t\t{4, {}},},
};
U_BOOT_DEVICE(phandle_source2) = {
\t.name\t\t= "source",
@@ -444,11 +444,6 @@
};
void dm_populate_phandle_data(void) {
-\tdtv_phandle_source.clocks[0].node = DM_GET_DEVICE(phandle_target);
-\tdtv_phandle_source.clocks[1].node = DM_GET_DEVICE(phandle2_target);
-\tdtv_phandle_source.clocks[2].node = DM_GET_DEVICE(phandle3_target);
-\tdtv_phandle_source.clocks[3].node = DM_GET_DEVICE(phandle_target);
-\tdtv_phandle_source2.clocks[0].node = DM_GET_DEVICE(phandle_target);
}
''', data)
@@ -489,7 +484,7 @@
/* Node /phandle-source2 index 0 */
static struct dtd_source dtv_phandle_source2 = {
\t.clocks\t\t\t= {
-\t\t\t{NULL, {}},},
+\t\t\t{1, {}},},
};
U_BOOT_DEVICE(phandle_source2) = {
\t.name\t\t= "source",
@@ -499,7 +494,6 @@
};
void dm_populate_phandle_data(void) {
-\tdtv_phandle_source2.clocks[0].node = DM_GET_DEVICE(phandle_target);
}
''', data)
@@ -547,10 +541,10 @@
/* Node /phandle-source index 2 */
static struct dtd_source dtv_phandle_source = {
\t.cd_gpios\t\t= {
-\t\t\t{NULL, {}},
-\t\t\t{NULL, {11}},
-\t\t\t{NULL, {12, 13}},
-\t\t\t{NULL, {}},},
+\t\t\t{4, {}},
+\t\t\t{0, {11}},
+\t\t\t{1, {12, 13}},
+\t\t\t{4, {}},},
};
U_BOOT_DEVICE(phandle_source) = {
\t.name\t\t= "source",
@@ -562,7 +556,7 @@
/* Node /phandle-source2 index 3 */
static struct dtd_source dtv_phandle_source2 = {
\t.cd_gpios\t\t= {
-\t\t\t{NULL, {}},},
+\t\t\t{4, {}},},
};
U_BOOT_DEVICE(phandle_source2) = {
\t.name\t\t= "source",
@@ -572,11 +566,6 @@
};
void dm_populate_phandle_data(void) {
-\tdtv_phandle_source.cd_gpios[0].node = DM_GET_DEVICE(phandle_target);
-\tdtv_phandle_source.cd_gpios[1].node = DM_GET_DEVICE(phandle2_target);
-\tdtv_phandle_source.cd_gpios[2].node = DM_GET_DEVICE(phandle3_target);
-\tdtv_phandle_source.cd_gpios[3].node = DM_GET_DEVICE(phandle_target);
-\tdtv_phandle_source2.cd_gpios[0].node = DM_GET_DEVICE(phandle_target);
}
''', data)