diff options
author | Dave Jiang <dave.jiang@intel.com> | 2020-01-21 16:44:23 -0700 |
---|---|---|
committer | Vinod Koul <vkoul@kernel.org> | 2020-01-24 11:18:45 +0530 |
commit | 8f47d1a5e545f903cd049c42da31a3be36178447 (patch) | |
tree | 0a28a5b686d0fe2576b971edf1a2282ba66814ce /drivers/dma/idxd/init.c | |
parent | d1dfe5b8ac644a0ffccfe7af22abed7c80b34702 (diff) |
dmaengine: idxd: connect idxd to dmaengine subsystem
Add plumbing for dmaengine subsystem connection. The driver register a DMA
device per DSA device. The channels are dynamically registered when a
workqueue is configured to be "kernel:dmanegine" type.
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/157965026376.73301.13867988830650740445.stgit@djiang5-desk3.ch.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/dma/idxd/init.c')
-rw-r--r-- | drivers/dma/idxd/init.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 229386464923..cf6e1d89dd02 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -15,6 +15,8 @@ #include <linux/device.h> #include <linux/idr.h> #include <uapi/linux/idxd.h> +#include <linux/dmaengine.h> +#include "../dmaengine.h" #include "registers.h" #include "idxd.h" @@ -396,6 +398,32 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return 0; } +static void idxd_flush_pending_llist(struct idxd_irq_entry *ie) +{ + struct idxd_desc *desc, *itr; + struct llist_node *head; + + head = llist_del_all(&ie->pending_llist); + if (!head) + return; + + llist_for_each_entry_safe(desc, itr, head, llnode) { + idxd_dma_complete_txd(desc, IDXD_COMPLETE_ABORT); + idxd_free_desc(desc->wq, desc); + } +} + +static void idxd_flush_work_list(struct idxd_irq_entry *ie) +{ + struct idxd_desc *desc, *iter; + + list_for_each_entry_safe(desc, iter, &ie->work_list, list) { + list_del(&desc->list); + idxd_dma_complete_txd(desc, IDXD_COMPLETE_ABORT); + idxd_free_desc(desc->wq, desc); + } +} + static void idxd_shutdown(struct pci_dev *pdev) { struct idxd_device *idxd = pci_get_drvdata(pdev); @@ -419,6 +447,8 @@ static void idxd_shutdown(struct pci_dev *pdev) synchronize_irq(idxd->msix_entries[i].vector); if (i == 0) continue; + idxd_flush_pending_llist(irq_entry); + idxd_flush_work_list(irq_entry); } } |