mirror of https://gitee.com/openkylin/linux.git
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: c52ca47823
("dmaengine: idxd: add configuration component of driver")
Reported-by: Yixin Zhang <yixin.zhang@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Tested-by: Yixin Zhang <yixin.zhang@intel.com>
Link: https://lore.kernel.org/r/159311264246.1198.11955791213681679428.stgit@djiang5-desk3.ch.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
5b78fac4b1
commit
da32b28c95
|
@ -320,6 +320,31 @@ void idxd_wq_unmap_portal(struct idxd_wq *wq)
|
|||
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 */
|
||||
static inline bool idxd_is_enabled(struct idxd_device *idxd)
|
||||
{
|
||||
|
|
|
@ -290,6 +290,7 @@ int idxd_wq_enable(struct idxd_wq *wq);
|
|||
int idxd_wq_disable(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_disable_cleanup(struct idxd_wq *wq);
|
||||
|
||||
/* submission */
|
||||
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)
|
|||
idxd_unregister_dma_device(idxd);
|
||||
spin_lock_irqsave(&idxd->dev_lock, flags);
|
||||
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);
|
||||
module_put(THIS_MODULE);
|
||||
if (rc < 0)
|
||||
|
|
Loading…
Reference in New Issue