diff --git a/drivers/core/device.c b/drivers/core/device.c index 6bd4b26..7483405 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -227,7 +227,7 @@ int device_probe_child(struct udevice *dev, void *parent_priv) } dev->seq = seq; - ret = uclass_pre_probe_child(dev); + ret = uclass_pre_probe_device(dev); if (ret) goto fail; diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 289a5d2..98c15e5 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -391,9 +391,17 @@ int uclass_resolve_seq(struct udevice *dev) return seq; } -int uclass_pre_probe_child(struct udevice *dev) +int uclass_pre_probe_device(struct udevice *dev) { struct uclass_driver *uc_drv; + int ret; + + uc_drv = dev->uclass->uc_drv; + if (uc_drv->pre_probe) { + ret = uc_drv->pre_probe(dev); + if (ret) + return ret; + } if (!dev->parent) return 0; diff --git a/include/dm/test.h b/include/dm/test.h index 707c69e..b310e5f 100644 --- a/include/dm/test.h +++ b/include/dm/test.h @@ -44,6 +44,7 @@ enum { /* For uclass */ DM_TEST_OP_POST_BIND, DM_TEST_OP_PRE_UNBIND, + DM_TEST_OP_PRE_PROBE, DM_TEST_OP_POST_PROBE, DM_TEST_OP_PRE_REMOVE, DM_TEST_OP_INIT, diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h index f2f254a..ae2a93d 100644 --- a/include/dm/uclass-internal.h +++ b/include/dm/uclass-internal.h @@ -44,15 +44,16 @@ int uclass_bind_device(struct udevice *dev); int uclass_unbind_device(struct udevice *dev); /** - * uclass_pre_probe_child() - Deal with a child that is about to be probed + * uclass_pre_probe_device() - Deal with a device that is about to be probed * * Perform any pre-processing that is needed by the uclass before it can be - * probed. + * probed. This includes the uclass' pre-probe() method and the parent + * uclass' child_pre_probe() method. * * @dev: Pointer to the device * #return 0 on success, -ve on error */ -int uclass_pre_probe_child(struct udevice *dev); +int uclass_pre_probe_device(struct udevice *dev); /** * uclass_post_probe_device() - Deal with a device that has just been probed diff --git a/include/dm/uclass.h b/include/dm/uclass.h index d6c40c6..d57d804 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -53,6 +53,7 @@ struct udevice; * @id: ID number of this uclass * @post_bind: Called after a new device is bound to this uclass * @pre_unbind: Called before a device is unbound from this uclass + * @pre_probe: Called before a new device is probed * @post_probe: Called after a new device is probed * @pre_remove: Called before a device is removed * @child_post_bind: Called after a child is bound to a device in this uclass @@ -80,6 +81,7 @@ struct uclass_driver { enum uclass_id id; int (*post_bind)(struct udevice *dev); int (*pre_unbind)(struct udevice *dev); + int (*pre_probe)(struct udevice *dev); int (*post_probe)(struct udevice *dev); int (*pre_remove)(struct udevice *dev); int (*child_post_bind)(struct udevice *dev); diff --git a/test/dm/core.c b/test/dm/core.c index 7be28e4..990d390 100644 --- a/test/dm/core.c +++ b/test/dm/core.c @@ -141,6 +141,7 @@ static int dm_test_autoprobe(struct dm_test_state *dms) ut_assert(uc); ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]); + ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]); ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]); /* The root device should not be activated until needed */ @@ -167,8 +168,12 @@ static int dm_test_autoprobe(struct dm_test_state *dms) ut_assert(dms->root->flags & DM_FLAG_ACTIVATED); } - /* Our 3 dm_test_infox children should be passed to post_probe */ + /* + * Our 3 dm_test_info children should be passed to pre_probe and + * post_probe + */ ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]); + ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]); /* Also we can check the per-device data */ expected_base_add = 0; diff --git a/test/dm/test-uclass.c b/test/dm/test-uclass.c index 1b9a3fd..be91657 100644 --- a/test/dm/test-uclass.c +++ b/test/dm/test-uclass.c @@ -42,6 +42,17 @@ static int test_pre_unbind(struct udevice *dev) return 0; } +static int test_pre_probe(struct udevice *dev) +{ + struct dm_test_uclass_perdev_priv *priv = dev_get_uclass_priv(dev); + + dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]++; + ut_assert(priv); + ut_assert(!device_active(dev)); + + return 0; +} + static int test_post_probe(struct udevice *dev) { struct udevice *prev = list_entry(dev->uclass_node.prev, @@ -96,6 +107,7 @@ UCLASS_DRIVER(test) = { .id = UCLASS_TEST, .post_bind = test_post_bind, .pre_unbind = test_pre_unbind, + .pre_probe = test_pre_probe, .post_probe = test_post_probe, .pre_remove = test_pre_remove, .init = test_init,