Commit da32b28c authored by Dave Jiang's avatar Dave Jiang Committed by Vinod Koul

dmaengine: idxd: cleanup workqueue config after disabling

After disabling a device, we should clean up the internal state for
the wqs and zero out the configuration registers. Without doing so can cause
issues when the user reprogram the wqs.

Fixes: c52ca478 ("dmaengine: idxd: add configuration component of driver")
Reported-by: default avatarYixin Zhang <yixin.zhang@intel.com>
Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
Tested-by: default avatarYixin Zhang <yixin.zhang@intel.com>
Link: https://lore.kernel.org/r/159311264246.1198.11955791213681679428.stgit@djiang5-desk3.ch.intel.comSigned-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 5b78fac4
...@@ -320,6 +320,31 @@ void idxd_wq_unmap_portal(struct idxd_wq *wq) ...@@ -320,6 +320,31 @@ void idxd_wq_unmap_portal(struct idxd_wq *wq)
devm_iounmap(dev, wq->dportal); devm_iounmap(dev, wq->dportal);
} }
void idxd_wq_disable_cleanup(struct idxd_wq *wq)
{
struct idxd_device *idxd = wq->idxd;
struct device *dev = &idxd->pdev->dev;
int i, wq_offset;
lockdep_assert_held(&idxd->dev_lock);
memset(&wq->wqcfg, 0, sizeof(wq->wqcfg));
wq->type = IDXD_WQT_NONE;
wq->size = 0;
wq->group = NULL;
wq->threshold = 0;
wq->priority = 0;
clear_bit(WQ_FLAG_DEDICATED, &wq->flags);
memset(wq->name, 0, WQ_NAME_SIZE);
for (i = 0; i < 8; i++) {
wq_offset = idxd->wqcfg_offset + wq->id * 32 + i * sizeof(u32);
iowrite32(0, idxd->reg_base + wq_offset);
dev_dbg(dev, "WQ[%d][%d][%#x]: %#x\n",
wq->id, i, wq_offset,
ioread32(idxd->reg_base + wq_offset));
}
}
/* Device control bits */ /* Device control bits */
static inline bool idxd_is_enabled(struct idxd_device *idxd) static inline bool idxd_is_enabled(struct idxd_device *idxd)
{ {
......
...@@ -290,6 +290,7 @@ int idxd_wq_enable(struct idxd_wq *wq); ...@@ -290,6 +290,7 @@ int idxd_wq_enable(struct idxd_wq *wq);
int idxd_wq_disable(struct idxd_wq *wq); int idxd_wq_disable(struct idxd_wq *wq);
int idxd_wq_map_portal(struct idxd_wq *wq); int idxd_wq_map_portal(struct idxd_wq *wq);
void idxd_wq_unmap_portal(struct idxd_wq *wq); void idxd_wq_unmap_portal(struct idxd_wq *wq);
void idxd_wq_disable_cleanup(struct idxd_wq *wq);
/* submission */ /* submission */
int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc); int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc);
......
...@@ -315,6 +315,11 @@ static int idxd_config_bus_remove(struct device *dev) ...@@ -315,6 +315,11 @@ static int idxd_config_bus_remove(struct device *dev)
idxd_unregister_dma_device(idxd); idxd_unregister_dma_device(idxd);
spin_lock_irqsave(&idxd->dev_lock, flags); spin_lock_irqsave(&idxd->dev_lock, flags);
rc = idxd_device_disable(idxd); rc = idxd_device_disable(idxd);
for (i = 0; i < idxd->max_wqs; i++) {
struct idxd_wq *wq = &idxd->wqs[i];
idxd_wq_disable_cleanup(wq);
}
spin_unlock_irqrestore(&idxd->dev_lock, flags); spin_unlock_irqrestore(&idxd->dev_lock, flags);
module_put(THIS_MODULE); module_put(THIS_MODULE);
if (rc < 0) if (rc < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment