Merge tag 'v5.8-rc6' into locking/core, to pick up fixes
[linux-2.6-microblaze.git] / drivers / infiniband / hw / hfi1 / init.c
index 5eed436..cb7ad12 100644 (file)
@@ -830,6 +830,29 @@ wq_error:
        return -ENOMEM;
 }
 
+/**
+ * destroy_workqueues - destroy per port workqueues
+ * @dd: the hfi1_ib device
+ */
+static void destroy_workqueues(struct hfi1_devdata *dd)
+{
+       int pidx;
+       struct hfi1_pportdata *ppd;
+
+       for (pidx = 0; pidx < dd->num_pports; ++pidx) {
+               ppd = dd->pport + pidx;
+
+               if (ppd->hfi1_wq) {
+                       destroy_workqueue(ppd->hfi1_wq);
+                       ppd->hfi1_wq = NULL;
+               }
+               if (ppd->link_wq) {
+                       destroy_workqueue(ppd->link_wq);
+                       ppd->link_wq = NULL;
+               }
+       }
+}
+
 /**
  * enable_general_intr() - Enable the IRQs that will be handled by the
  * general interrupt handler.
@@ -1103,15 +1126,10 @@ static void shutdown_device(struct hfi1_devdata *dd)
                 * We can't count on interrupts since we are stopping.
                 */
                hfi1_quiet_serdes(ppd);
-
-               if (ppd->hfi1_wq) {
-                       destroy_workqueue(ppd->hfi1_wq);
-                       ppd->hfi1_wq = NULL;
-               }
-               if (ppd->link_wq) {
-                       destroy_workqueue(ppd->link_wq);
-                       ppd->link_wq = NULL;
-               }
+               if (ppd->hfi1_wq)
+                       flush_workqueue(ppd->hfi1_wq);
+               if (ppd->link_wq)
+                       flush_workqueue(ppd->link_wq);
        }
        sdma_exit(dd);
 }
@@ -1756,6 +1774,7 @@ static void remove_one(struct pci_dev *pdev)
         * clear dma engines, etc.
         */
        shutdown_device(dd);
+       destroy_workqueues(dd);
 
        stop_timers(dd);