summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2015-03-25 12:21:56 -0600
committerSimon Glass <sjg@chromium.org>2015-04-18 11:11:19 -0600
commit206d4d2b4b30889678bb6b064002013a427b1501 (patch)
tree9683b0ddd1824d6f21a269fd05099fe934242321
parent39de843352d8c655f23ecff460d5e74101780b7e (diff)
dm: core: Mark device as active before calling uclass probe() methods
The uclass pre-probe functions may end up calling back into the device in some circumstances. This can fail if recursion takes place. Adjust the ordering so that we mark the device as active early, then retract this later if needed. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Marek Vasut <marex@denx.de>
-rw-r--r--drivers/core/device.c8
-rw-r--r--test/dm/test-uclass.c3
2 files changed, 7 insertions, 4 deletions
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 4fba11857c..b7ed21c003 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -243,6 +243,8 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
}
dev->seq = seq;
+ dev->flags |= DM_FLAG_ACTIVATED;
+
ret = uclass_pre_probe_device(dev);
if (ret)
goto fail;
@@ -269,10 +271,8 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
}
ret = uclass_post_probe_device(dev);
- if (ret) {
- dev->flags &= ~DM_FLAG_ACTIVATED;
+ if (ret)
goto fail_uclass;
- }
return 0;
fail_uclass:
@@ -281,6 +281,8 @@ fail_uclass:
__func__, dev->name);
}
fail:
+ dev->flags &= ~DM_FLAG_ACTIVATED;
+
dev->seq = -1;
device_free(dev);
diff --git a/test/dm/test-uclass.c b/test/dm/test-uclass.c
index be91657347..7cb37f70c7 100644
--- a/test/dm/test-uclass.c
+++ b/test/dm/test-uclass.c
@@ -31,6 +31,7 @@ int test_ping(struct udevice *dev, int pingval, int *pingret)
static int test_post_bind(struct udevice *dev)
{
dm_testdrv_op_count[DM_TEST_OP_POST_BIND]++;
+ ut_assert(!device_active(dev));
return 0;
}
@@ -48,7 +49,7 @@ static int test_pre_probe(struct udevice *dev)
dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]++;
ut_assert(priv);
- ut_assert(!device_active(dev));
+ ut_assert(device_active(dev));
return 0;
}