dpaa2-mac: return -EPROBE_DEFER from dpaa2_mac_open in case the fwnode is not set
authorIoana Ciornei <ioana.ciornei@nxp.com>
Thu, 6 Jan 2022 13:59:04 +0000 (15:59 +0200)
committerJakub Kicinski <kuba@kernel.org>
Fri, 7 Jan 2022 03:49:10 +0000 (19:49 -0800)
We could get into a situation when the fwnode of the parent device is
not yet set because its probe didn't yet finish. When this happens, any
caller of the dpaa2_mac_open() will not have the fwnode available, thus
cause problems at the PHY connect time.

Avoid this by just returning -EPROBE_DEFER from the dpaa2_mac_open when
this happens.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c

index e80376c..623d113 100644 (file)
@@ -54,6 +54,12 @@ static struct fwnode_handle *dpaa2_mac_get_node(struct device *dev,
                parent = of_fwnode_handle(dpmacs);
        } else if (is_acpi_node(fwnode)) {
                parent = fwnode;
+       } else {
+               /* The root dprc device didn't yet get to finalize it's probe,
+                * thus the fwnode field is not yet set. Defer probe if we are
+                * facing this situation.
+                */
+               return ERR_PTR(-EPROBE_DEFER);
        }
 
        if (!parent)
@@ -330,6 +336,7 @@ int dpaa2_mac_open(struct dpaa2_mac *mac)
 {
        struct fsl_mc_device *dpmac_dev = mac->mc_dev;
        struct net_device *net_dev = mac->net_dev;
+       struct fwnode_handle *fw_node;
        int err;
 
        err = dpmac_open(mac->mc_io, 0, dpmac_dev->obj_desc.id,
@@ -349,7 +356,13 @@ int dpaa2_mac_open(struct dpaa2_mac *mac)
        /* Find the device node representing the MAC device and link the device
         * behind the associated netdev to it.
         */
-       mac->fw_node = dpaa2_mac_get_node(&mac->mc_dev->dev, mac->attr.id);
+       fw_node = dpaa2_mac_get_node(&mac->mc_dev->dev, mac->attr.id);
+       if (IS_ERR(fw_node)) {
+               err = PTR_ERR(fw_node);
+               goto err_close_dpmac;
+       }
+
+       mac->fw_node = fw_node;
        net_dev->dev.of_node = to_of_node(mac->fw_node);
 
        return 0;