struct mlxsw_thermal *thermal;
        struct mlxsw_core_port *ports;
        unsigned int max_ports;
+       bool reload_fail;
        unsigned long driver_priv[0];
        /* driver_priv has to be always the last item */
 };
                                                     pool_type, p_cur, p_max);
 }
 
+static int mlxsw_devlink_core_bus_device_reload(struct devlink *devlink)
+{
+       struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
+       const struct mlxsw_bus *mlxsw_bus = mlxsw_core->bus;
+       int err;
+
+       if (!mlxsw_bus->reset)
+               return -EOPNOTSUPP;
+
+       mlxsw_core_bus_device_unregister(mlxsw_core, true);
+       mlxsw_bus->reset(mlxsw_core->bus_priv);
+       err = mlxsw_core_bus_device_register(mlxsw_core->bus_info,
+                                            mlxsw_core->bus,
+                                            mlxsw_core->bus_priv, true,
+                                            devlink);
+       if (err)
+               mlxsw_core->reload_fail = true;
+       return err;
+}
+
 static const struct devlink_ops mlxsw_devlink_ops = {
+       .reload                         = mlxsw_devlink_core_bus_device_reload,
        .port_type_set                  = mlxsw_devlink_port_type_set,
        .port_split                     = mlxsw_devlink_port_split,
        .port_unsplit                   = mlxsw_devlink_port_unsplit,
 
 int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
                                   const struct mlxsw_bus *mlxsw_bus,
-                                  void *bus_priv)
+                                  void *bus_priv, bool reload,
+                                  struct devlink *devlink)
 {
        const char *device_kind = mlxsw_bus_info->device_kind;
        struct mlxsw_core *mlxsw_core;
        struct mlxsw_driver *mlxsw_driver;
-       struct devlink *devlink;
        size_t alloc_size;
        int err;
 
        mlxsw_driver = mlxsw_core_driver_get(device_kind);
        if (!mlxsw_driver)
                return -EINVAL;
-       alloc_size = sizeof(*mlxsw_core) + mlxsw_driver->priv_size;
-       devlink = devlink_alloc(&mlxsw_devlink_ops, alloc_size);
-       if (!devlink) {
-               err = -ENOMEM;
-               goto err_devlink_alloc;
+
+       if (!reload) {
+               alloc_size = sizeof(*mlxsw_core) + mlxsw_driver->priv_size;
+               devlink = devlink_alloc(&mlxsw_devlink_ops, alloc_size);
+               if (!devlink) {
+                       err = -ENOMEM;
+                       goto err_devlink_alloc;
+               }
        }
 
        mlxsw_core = devlink_priv(devlink);
        if (err)
                goto err_bus_init;
 
-       if (mlxsw_driver->resources_register) {
+       if (mlxsw_driver->resources_register && !reload) {
                err = mlxsw_driver->resources_register(mlxsw_core);
                if (err)
                        goto err_register_resources;
        if (err)
                goto err_emad_init;
 
-       err = devlink_register(devlink, mlxsw_bus_info->dev);
-       if (err)
-               goto err_devlink_register;
+       if (!reload) {
+               err = devlink_register(devlink, mlxsw_bus_info->dev);
+               if (err)
+                       goto err_devlink_register;
+       }
 
        err = mlxsw_hwmon_init(mlxsw_core, mlxsw_bus_info, &mlxsw_core->hwmon);
        if (err)
        mlxsw_thermal_fini(mlxsw_core->thermal);
 err_thermal_init:
 err_hwmon_init:
-       devlink_unregister(devlink);
+       if (!reload)
+               devlink_unregister(devlink);
 err_devlink_register:
        mlxsw_emad_fini(mlxsw_core);
 err_emad_init:
 err_ports_init:
        mlxsw_bus->fini(bus_priv);
 err_bus_init:
-       devlink_resources_unregister(devlink, NULL);
+       if (!reload)
+               devlink_resources_unregister(devlink, NULL);
 err_register_resources:
-       devlink_free(devlink);
+       if (!reload)
+               devlink_free(devlink);
 err_devlink_alloc:
        mlxsw_core_driver_put(device_kind);
        return err;
 }
 EXPORT_SYMBOL(mlxsw_core_bus_device_register);
 
-void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core)
+void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
+                                     bool reload)
 {
        const char *device_kind = mlxsw_core->bus_info->device_kind;
        struct devlink *devlink = priv_to_devlink(mlxsw_core);
 
+       if (mlxsw_core->reload_fail)
+               goto reload_fail;
+
        if (mlxsw_core->driver->fini)
                mlxsw_core->driver->fini(mlxsw_core);
        mlxsw_thermal_fini(mlxsw_core->thermal);
-       devlink_unregister(devlink);
+       if (!reload)
+               devlink_unregister(devlink);
        mlxsw_emad_fini(mlxsw_core);
        kfree(mlxsw_core->lag.mapping);
        mlxsw_ports_fini(mlxsw_core);
-       devlink_resources_unregister(devlink, NULL);
+       if (!reload)
+               devlink_resources_unregister(devlink, NULL);
        mlxsw_core->bus->fini(mlxsw_core->bus_priv);
+       if (reload)
+               return;
+reload_fail:
        devlink_free(devlink);
        mlxsw_core_driver_put(device_kind);
 }