pr_debug("%s: returning\n", __func__);
 }
 
+/**
+ * notify_shutdown() - notifies device of pending shutdown
+ * @cfg:       Internal structure associated with the host.
+ * @wait:      Whether to wait for shutdown processing to complete.
+ *
+ * This function will notify the AFU that the adapter is being shutdown
+ * and will wait for shutdown processing to complete if wait is true.
+ * This notification should flush pending I/Os to the device and halt
+ * further I/Os until the next AFU reset is issued and device restarted.
+ */
+static void notify_shutdown(struct cxlflash_cfg *cfg, bool wait)
+{
+       struct afu *afu = cfg->afu;
+       struct device *dev = &cfg->dev->dev;
+       struct sisl_global_map __iomem *global = &afu->afu_map->global;
+       struct dev_dependent_vals *ddv;
+       u64 reg, status;
+       int i, retry_cnt = 0;
+
+       ddv = (struct dev_dependent_vals *)cfg->dev_id->driver_data;
+       if (!(ddv->flags & CXLFLASH_NOTIFY_SHUTDOWN))
+               return;
+
+       /* Notify AFU */
+       for (i = 0; i < NUM_FC_PORTS; i++) {
+               reg = readq_be(&global->fc_regs[i][FC_CONFIG2 / 8]);
+               reg |= SISL_FC_SHUTDOWN_NORMAL;
+               writeq_be(reg, &global->fc_regs[i][FC_CONFIG2 / 8]);
+       }
+
+       if (!wait)
+               return;
+
+       /* Wait up to 1.5 seconds for shutdown processing to complete */
+       for (i = 0; i < NUM_FC_PORTS; i++) {
+               retry_cnt = 0;
+               while (true) {
+                       status = readq_be(&global->fc_regs[i][FC_STATUS / 8]);
+                       if (status & SISL_STATUS_SHUTDOWN_COMPLETE)
+                               break;
+                       if (++retry_cnt >= MC_RETRY_CNT) {
+                               dev_dbg(dev, "%s: port %d shutdown processing "
+                                       "not yet completed\n", __func__, i);
+                               break;
+                       }
+                       msleep(100 * retry_cnt);
+               }
+       }
+}
+
+/**
+ * cxlflash_shutdown() - shutdown handler
+ * @pdev:      PCI device associated with the host.
+ */
+static void cxlflash_shutdown(struct pci_dev *pdev)
+{
+       struct cxlflash_cfg *cfg = pci_get_drvdata(pdev);
+
+       notify_shutdown(cfg, false);
+}
+
 /**
  * cxlflash_remove() - PCI entry point to tear down host
  * @pdev:      PCI device associated with the host.
                                                  cfg->tmf_slock);
        spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags);
 
+       /* Notify AFU and wait for shutdown processing to complete */
+       notify_shutdown(cfg, true);
+
        cfg->state = STATE_FAILTERM;
        cxlflash_stop_term_user_contexts(cfg);
 
 static struct dev_dependent_vals dev_corsa_vals = { CXLFLASH_MAX_SECTORS,
                                        0ULL };
 static struct dev_dependent_vals dev_flash_gt_vals = { CXLFLASH_MAX_SECTORS,
-                                       0ULL };
+                                       CXLFLASH_NOTIFY_SHUTDOWN };
 
 /*
  * PCI device binding table
        .id_table = cxlflash_pci_table,
        .probe = cxlflash_probe,
        .remove = cxlflash_remove,
+       .shutdown = cxlflash_shutdown,
        .err_handler = &cxlflash_err_handler,
 };