]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
dm: core: Do not stop uclass iteration on error
authorMichal Suchanek <msuchanek@suse.de>
Wed, 12 Oct 2022 19:58:09 +0000 (21:58 +0200)
committerSimon Glass <sjg@chromium.org>
Sat, 29 Oct 2022 13:36:33 +0000 (07:36 -0600)
When probing a device fails NULL pointer is returned, and following
devices in uclass list cannot be iterated. Skip to next device on error
instead.

With that the only condition under which these simple iteration
functions return error is when the dm is not initialized at uclass_get
time. This is not all that interesting, change return type to void.

Fixes: 6494d708bf ("dm: Add base driver model support")
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
drivers/core/uclass.c
include/dm/uclass.h
test/dm/core.c
test/dm/test-fdt.c

index b7d11bdd23a4d9a27a7de4637062459f5b1a0c64..1762a0796dbde21297e5c8a357b969de20bfd6f0 100644 (file)
@@ -574,28 +574,34 @@ int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent,
 }
 #endif
 
-int uclass_first_device(enum uclass_id id, struct udevice **devp)
+/*
+ * Starting from the given device @dev, return pointer to the first device in
+ * the uclass that probes successfully in @devp.
+ */
+static void _uclass_next_device(struct udevice *dev, struct udevice **devp)
+{
+       for (; dev; uclass_find_next_device(&dev)) {
+               if (!device_probe(dev))
+                       break;
+       }
+       *devp = dev;
+}
+
+void uclass_first_device(enum uclass_id id, struct udevice **devp)
 {
        struct udevice *dev;
        int ret;
 
-       *devp = NULL;
        ret = uclass_find_first_device(id, &dev);
-       if (!dev)
-               return 0;
-       return uclass_get_device_tail(dev, ret, devp);
+       _uclass_next_device(dev, devp);
 }
 
-int uclass_next_device(struct udevice **devp)
+void uclass_next_device(struct udevice **devp)
 {
        struct udevice *dev = *devp;
-       int ret;
 
-       *devp = NULL;
-       ret = uclass_find_next_device(&dev);
-       if (!dev)
-               return 0;
-       return uclass_get_device_tail(dev, ret, devp);
+       uclass_find_next_device(&dev);
+       _uclass_next_device(dev, devp);
 }
 
 int uclass_first_device_err(enum uclass_id id, struct udevice **devp)
index b1c016ef9f59911202e0200d906bb581f42ad9ba..ee15c920633a32da876de6df03a33779cff69819 100644 (file)
@@ -320,32 +320,31 @@ int uclass_get_device_by_driver(enum uclass_id id, const struct driver *drv,
  * uclass_first_device() - Get the first device in a uclass
  *
  * The device returned is probed if necessary, and ready for use
+ * Devices that fail to probe are skipped
  *
  * This function is useful to start iterating through a list of devices which
  * are functioning correctly and can be probed.
  *
  * @id: Uclass ID to look up
  * @devp: Returns pointer to the first device in that uclass if no error
- * occurred, or NULL if there is no first device, or an error occurred with
- * that device.
- * Return: 0 if OK (found or not found), other -ve on error
+ * occurred, or NULL if there is no usable device
  */
-int uclass_first_device(enum uclass_id id, struct udevice **devp);
+void uclass_first_device(enum uclass_id id, struct udevice **devp);
 
 /**
  * uclass_next_device() - Get the next device in a uclass
  *
  * The device returned is probed if necessary, and ready for use
+ * Devices that fail to probe are skipped
  *
  * This function is useful to iterate through a list of devices which
  * are functioning correctly and can be probed.
  *
  * @devp: On entry, pointer to device to lookup. On exit, returns pointer
  * to the next device in the uclass if no error occurred, or NULL if there is
- * no next device, or an error occurred with that next device.
- * Return: 0 if OK (found or not found), other -ve on error
+ * no next device
  */
-int uclass_next_device(struct udevice **devp);
+void uclass_next_device(struct udevice **devp);
 
 /**
  * uclass_first_device_err() - Get the first device in a uclass
index 84eb76ed5fc8f931232ac29ad1f8974fa042cb45..7f3f8d183bca4af336e60c32ad380e7d166f9d88 100644 (file)
@@ -1078,11 +1078,10 @@ static int dm_test_uclass_devices_get(struct unit_test_state *uts)
        struct udevice *dev;
        int ret;
 
-       for (ret = uclass_first_device(UCLASS_TEST, &dev);
+       for (ret = uclass_first_device_check(UCLASS_TEST, &dev);
             dev;
-            ret = uclass_next_device(&dev)) {
+            ret = uclass_next_device_check(&dev)) {
                ut_assert(!ret);
-               ut_assert(dev);
                ut_assert(device_active(dev));
        }
 
@@ -1112,11 +1111,10 @@ static int dm_test_uclass_devices_get_by_name(struct unit_test_state *uts)
         * this will fail on checking condition: testdev == finddev, since the
         * uclass_get_device_by_name(), returns the first device by given name.
        */
-       for (ret = uclass_first_device(UCLASS_TEST_FDT, &testdev);
+       for (ret = uclass_first_device_check(UCLASS_TEST_FDT, &testdev);
             testdev;
-            ret = uclass_next_device(&testdev)) {
+            ret = uclass_next_device_check(&testdev)) {
                ut_assertok(ret);
-               ut_assert(testdev);
                ut_assert(device_active(testdev));
 
                findret = uclass_get_device_by_name(UCLASS_TEST_FDT,
index 1f14513d9f10323eb97435ea8f36df367e5f40d0..8bb868b67871e078a74c4c0bd558409fca0a0478 100644 (file)
@@ -403,13 +403,12 @@ static int dm_test_first_next_device_probeall(struct unit_test_state *uts)
        int ret;
 
        /* There should be 4 devices */
-       for (ret = uclass_first_device(UCLASS_TEST_PROBE, &dev), count = 0;
+       for (uclass_first_device(UCLASS_TEST_PROBE, &dev), count = 0;
             dev;
-            ret = uclass_next_device(&dev)) {
+            uclass_next_device(&dev)) {
                count++;
                parent = dev_get_parent(dev);
                }
-       ut_assertok(ret);
        ut_asserteq(4, count);
 
        /* Remove them and try again, with an error on the second one */
@@ -417,16 +416,30 @@ static int dm_test_first_next_device_probeall(struct unit_test_state *uts)
        pdata = dev_get_plat(dev);
        pdata->probe_err = -ENOMEM;
        device_remove(parent, DM_REMOVE_NORMAL);
-       ut_assertok(uclass_first_device(UCLASS_TEST_PROBE, &dev));
-       ut_asserteq(-ENOMEM, uclass_next_device(&dev));
-       ut_asserteq_ptr(dev, NULL);
+       for (ret = uclass_first_device_check(UCLASS_TEST_PROBE, &dev),
+               count = 0;
+            dev;
+            ret = uclass_next_device_check(&dev)) {
+               if (!ret)
+                       count++;
+               else
+                       ut_asserteq(-ENOMEM, ret);
+               parent = dev_get_parent(dev);
+               }
+       ut_asserteq(3, count);
 
        /* Now an error on the first one */
        ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 0, &dev));
        pdata = dev_get_plat(dev);
        pdata->probe_err = -ENOENT;
        device_remove(parent, DM_REMOVE_NORMAL);
-       ut_asserteq(-ENOENT, uclass_first_device(UCLASS_TEST_PROBE, &dev));
+       for (uclass_first_device(UCLASS_TEST_PROBE, &dev), count = 0;
+            dev;
+            uclass_next_device(&dev)) {
+               count++;
+               parent = dev_get_parent(dev);
+               }
+       ut_asserteq(2, count);
 
        /* Now that broken devices are set up test probe_all */
        device_remove(parent, DM_REMOVE_NORMAL);