From: Dave Jiang Date: Mon, 27 Jul 2020 16:37:11 +0000 (-0700) Subject: dmaengine: idxd: reset states after device disable or reset X-Git-Tag: v5.10.7~1710^2~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=df841b17e809f48f740cd2dd8b63543073c91a02;p=platform%2Fkernel%2Flinux-rpi.git dmaengine: idxd: reset states after device disable or reset The state for WQs should be reset to disabled when a device is reset or disabled. Fixes: da32b28c95a7 ("dmaengine: idxd: cleanup workqueue config after disabling") Reported-by: Mona Hossain Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/159586777684.27150.17589406415773568534.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 14b4585..b75d699 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -410,10 +410,27 @@ int idxd_device_enable(struct idxd_device *idxd) return 0; } +void idxd_device_wqs_clear_state(struct idxd_device *idxd) +{ + int i; + + lockdep_assert_held(&idxd->dev_lock); + + for (i = 0; i < idxd->max_wqs; i++) { + struct idxd_wq *wq = &idxd->wqs[i]; + + if (wq->state == IDXD_WQ_ENABLED) { + idxd_wq_disable_cleanup(wq); + wq->state = IDXD_WQ_DISABLED; + } + } +} + int idxd_device_disable(struct idxd_device *idxd) { struct device *dev = &idxd->pdev->dev; u32 status; + unsigned long flags; if (!idxd_is_enabled(idxd)) { dev_dbg(dev, "Device is not enabled\n"); @@ -429,13 +446,22 @@ int idxd_device_disable(struct idxd_device *idxd) return -ENXIO; } + spin_lock_irqsave(&idxd->dev_lock, flags); + idxd_device_wqs_clear_state(idxd); idxd->state = IDXD_DEV_CONF_READY; + spin_unlock_irqrestore(&idxd->dev_lock, flags); return 0; } void idxd_device_reset(struct idxd_device *idxd) { + unsigned long flags; + idxd_cmd_exec(idxd, IDXD_CMD_RESET_DEVICE, 0, NULL); + spin_lock_irqsave(&idxd->dev_lock, flags); + idxd_device_wqs_clear_state(idxd); + idxd->state = IDXD_DEV_CONF_READY; + spin_unlock_irqrestore(&idxd->dev_lock, flags); } /* Device configuration bits */ diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c index b514255..1e9e699 100644 --- a/drivers/dma/idxd/irq.c +++ b/drivers/dma/idxd/irq.c @@ -11,18 +11,6 @@ #include "idxd.h" #include "registers.h" -void idxd_device_wqs_clear_state(struct idxd_device *idxd) -{ - int i; - - lockdep_assert_held(&idxd->dev_lock); - for (i = 0; i < idxd->max_wqs; i++) { - struct idxd_wq *wq = &idxd->wqs[i]; - - wq->state = IDXD_WQ_DISABLED; - } -} - static void idxd_device_reinit(struct work_struct *work) { struct idxd_device *idxd = container_of(work, struct idxd_device, work);