struct mlxsw_linecard *linecard = linecard_bdev->linecard;
        struct mlxsw_linecard_dev *linecard_dev;
        struct devlink *devlink;
+       int err;
 
        devlink = devlink_alloc(&mlxsw_linecard_dev_devlink_ops,
                                sizeof(*linecard_dev), &adev->dev);
        linecard_dev->linecard = linecard_bdev->linecard;
        linecard_bdev->linecard_dev = linecard_dev;
 
+       err = devlink_linecard_nested_dl_set(linecard->devlink_linecard, devlink);
+       if (err) {
+               devlink_free(devlink);
+               return err;
+       }
        devlink_register(devlink);
-       devlink_linecard_nested_dl_set(linecard->devlink_linecard, devlink);
        return 0;
 }
 
        struct mlxsw_linecard_bdev *linecard_bdev =
                        container_of(adev, struct mlxsw_linecard_bdev, adev);
        struct devlink *devlink = priv_to_devlink(linecard_bdev->linecard_dev);
-       struct mlxsw_linecard *linecard = linecard_bdev->linecard;
 
-       devlink_linecard_nested_dl_set(linecard->devlink_linecard, NULL);
        devlink_unregister(devlink);
        devlink_free(devlink);
 }
 
 void devlink_linecard_provision_fail(struct devlink_linecard *linecard);
 void devlink_linecard_activate(struct devlink_linecard *linecard);
 void devlink_linecard_deactivate(struct devlink_linecard *linecard);
-void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
-                                   struct devlink *nested_devlink);
+int devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
+                                  struct devlink *nested_devlink);
 int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
                     u32 size, u16 ingress_pools_count,
                     u16 egress_pools_count, u16 ingress_tc_count,
 
        const char *type;
        struct devlink_linecard_type *types;
        unsigned int types_count;
-       struct devlink *nested_devlink;
+       u32 rel_index;
 };
 
 unsigned int devlink_linecard_index(struct devlink_linecard *linecard)
                nla_nest_end(msg, attr);
        }
 
-       if (linecard->nested_devlink &&
-           devlink_nl_put_nested_handle(msg, devlink_net(devlink),
-                                        linecard->nested_devlink,
-                                        DEVLINK_ATTR_NESTED_DEVLINK))
+       if (devlink_rel_devlink_handle_put(msg, devlink,
+                                          linecard->rel_index,
+                                          DEVLINK_ATTR_NESTED_DEVLINK,
+                                          NULL))
                goto nla_put_failure;
 
        genlmsg_end(msg, hdr);
 void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
 {
        mutex_lock(&linecard->state_lock);
-       WARN_ON(linecard->nested_devlink);
        linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
        linecard->type = NULL;
        devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
 void devlink_linecard_provision_fail(struct devlink_linecard *linecard)
 {
        mutex_lock(&linecard->state_lock);
-       WARN_ON(linecard->nested_devlink);
        linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED;
        devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
        mutex_unlock(&linecard->state_lock);
 }
 EXPORT_SYMBOL_GPL(devlink_linecard_deactivate);
 
+static void devlink_linecard_rel_notify_cb(struct devlink *devlink,
+                                          u32 linecard_index)
+{
+       struct devlink_linecard *linecard;
+
+       linecard = devlink_linecard_get_by_index(devlink, linecard_index);
+       if (!linecard)
+               return;
+       devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
+}
+
+static void devlink_linecard_rel_cleanup_cb(struct devlink *devlink,
+                                           u32 linecard_index, u32 rel_index)
+{
+       struct devlink_linecard *linecard;
+
+       linecard = devlink_linecard_get_by_index(devlink, linecard_index);
+       if (linecard && linecard->rel_index == rel_index)
+               linecard->rel_index = 0;
+}
+
 /**
  *     devlink_linecard_nested_dl_set - Attach/detach nested devlink
  *                                      instance to linecard.
  *     @linecard: devlink linecard
  *     @nested_devlink: devlink instance to attach or NULL to detach
  */
-void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
-                                   struct devlink *nested_devlink)
+int devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
+                                  struct devlink *nested_devlink)
 {
-       mutex_lock(&linecard->state_lock);
-       linecard->nested_devlink = nested_devlink;
-       devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
-       mutex_unlock(&linecard->state_lock);
+       return devlink_rel_nested_in_add(&linecard->rel_index,
+                                        linecard->devlink->index,
+                                        linecard->index,
+                                        devlink_linecard_rel_notify_cb,
+                                        devlink_linecard_rel_cleanup_cb,
+                                        nested_devlink);
 }
 EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set);