Merge tag 'dmaengine-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul...
[platform/kernel/linux-rpi.git] / drivers / dma / idxd / device.c
index 7c74bc6..22d6f4e 100644 (file)
@@ -299,21 +299,6 @@ void idxd_wqs_unmap_portal(struct idxd_device *idxd)
        }
 }
 
-static void __idxd_wq_set_priv_locked(struct idxd_wq *wq, int priv)
-{
-       struct idxd_device *idxd = wq->idxd;
-       union wqcfg wqcfg;
-       unsigned int offset;
-
-       offset = WQCFG_OFFSET(idxd, wq->id, WQCFG_PRIVL_IDX);
-       spin_lock(&idxd->dev_lock);
-       wqcfg.bits[WQCFG_PRIVL_IDX] = ioread32(idxd->reg_base + offset);
-       wqcfg.priv = priv;
-       wq->wqcfg->bits[WQCFG_PRIVL_IDX] = wqcfg.bits[WQCFG_PRIVL_IDX];
-       iowrite32(wqcfg.bits[WQCFG_PRIVL_IDX], idxd->reg_base + offset);
-       spin_unlock(&idxd->dev_lock);
-}
-
 static void __idxd_wq_set_pasid_locked(struct idxd_wq *wq, int pasid)
 {
        struct idxd_device *idxd = wq->idxd;
@@ -384,9 +369,7 @@ static void idxd_wq_disable_cleanup(struct idxd_wq *wq)
        wq->threshold = 0;
        wq->priority = 0;
        wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES;
-       clear_bit(WQ_FLAG_DEDICATED, &wq->flags);
-       clear_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags);
-       clear_bit(WQ_FLAG_ATS_DISABLE, &wq->flags);
+       wq->flags = 0;
        memset(wq->name, 0, WQ_NAME_SIZE);
        wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER;
        idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH);
@@ -1421,15 +1404,14 @@ int drv_enable_wq(struct idxd_wq *wq)
        }
 
        /*
-        * In the event that the WQ is configurable for pasid and priv bits.
-        * For kernel wq, the driver should setup the pasid, pasid_en, and priv bit.
-        * However, for non-kernel wq, the driver should only set the pasid_en bit for
-        * shared wq. A dedicated wq that is not 'kernel' type will configure pasid and
+        * In the event that the WQ is configurable for pasid, the driver
+        * should setup the pasid, pasid_en bit. This is true for both kernel
+        * and user shared workqueues. There is no need to setup priv bit in
+        * that in-kernel DMA will also do user privileged requests.
+        * A dedicated wq that is not 'kernel' type will configure pasid and
         * pasid_en later on so there is no need to setup.
         */
        if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) {
-               int priv = 0;
-
                if (wq_pasid_enabled(wq)) {
                        if (is_idxd_wq_kernel(wq) || wq_shared(wq)) {
                                u32 pasid = wq_dedicated(wq) ? idxd->pasid : 0;
@@ -1437,10 +1419,6 @@ int drv_enable_wq(struct idxd_wq *wq)
                                __idxd_wq_set_pasid_locked(wq, pasid);
                        }
                }
-
-               if (is_idxd_wq_kernel(wq))
-                       priv = 1;
-               __idxd_wq_set_priv_locked(wq, priv);
        }
 
        rc = 0;
@@ -1548,6 +1526,15 @@ int idxd_device_drv_probe(struct idxd_dev *idxd_dev)
        if (rc < 0)
                return -ENXIO;
 
+       /*
+        * System PASID is preserved across device disable/enable cycle, but
+        * genconfig register content gets cleared during device reset. We
+        * need to re-enable user interrupts for kernel work queue completion
+        * IRQ to function.
+        */
+       if (idxd->pasid != IOMMU_PASID_INVALID)
+               idxd_set_user_intr(idxd, 1);
+
        rc = idxd_device_evl_setup(idxd);
        if (rc < 0) {
                idxd->cmd_status = IDXD_SCMD_DEV_EVL_ERR;