new file mode 100644
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This file contains recovery handler.
+ *
+ * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates.
+ */
+
+#include "core.h"
+#include "if.h"
+#include "params.h"
+#include "dbg.h"
+#include "recovery.h"
+
+#define RA6W_RECOVERY_WQ_NAME "ra6w_recovery_wq"
+
+static bool ra6w_recovery_reprobe;
+
+void ra6w_recovery_reprobe_set(bool set)
+{
+ ra6w_recovery_reprobe = set;
+}
+
+bool ra6w_recovery_reprobe_get(void)
+{
+ return ra6w_recovery_reprobe;
+}
+
+void ra6w_recovery_event_post(struct ra6w_recovery *recovery)
+{
+ struct ra6w_core *core = container_of(recovery, struct ra6w_core, recovery);
+
+ if (!recovery->wq)
+ return;
+
+ if (recovery->in_recovery)
+ return;
+
+ ra6w_ctrl_dev_hw_reset(&core->ctrl);
+ recovery->in_recovery = true;
+
+ queue_work(recovery->wq, &recovery->work);
+}
+
+static void ra6w_recovery_process(struct ra6w_recovery *recovery)
+{
+ struct ra6w_core *core = container_of(recovery, struct ra6w_core, recovery);
+ struct ra6w_if *ifp = container_of(core, struct ra6w_if, core);
+
+ ra6w_info("recovery start\n");
+
+ ra6w_sdio_reprobe(ifp->dev.func);
+
+ ra6w_recovery_reprobe_set(true);
+}
+
+static void ra6w_recovery_handler(struct work_struct *work)
+{
+ struct ra6w_recovery *recovery = container_of(work, struct ra6w_recovery, work);
+
+ ra6w_recovery_process(recovery);
+}
+
+int ra6w_recovery_init(struct ra6w_recovery *recovery)
+{
+ struct workqueue_struct *wq;
+
+ wq = create_singlethread_workqueue(RA6W_RECOVERY_WQ_NAME);
+ if (!wq) {
+ ra6w_err("[%s] create workqueue %s failed\n", __func__, RA6W_RECOVERY_WQ_NAME);
+ return -ENOENT;
+ }
+
+ INIT_WORK(&recovery->work, ra6w_recovery_handler);
+ recovery->wq = wq;
+
+ return 0;
+}
+
+void ra6w_recovery_deinit(struct ra6w_recovery *recovery)
+{
+ cancel_work_sync(&recovery->work);
+
+ if (recovery->wq)
+ destroy_workqueue(recovery->wq);
+
+ recovery->wq = NULL;
+}