Commit cedd54f7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'dmaengine-fix-5.7-rc7' of git://git.infradead.org/users/vkoul/slave-dma

Pull dmaengine fixes from Vinod Koul:
 "Some driver fixes:

   - dmatest restoration of defaults

   - tegra210-adma probe handling fix

   - k3-udma flags fixed for slave_sg and memcpy

   - list fix for zynqmp_dma

   - idxd interrupt completion fix

   - lock fix for owl"

* tag 'dmaengine-fix-5.7-rc7' of git://git.infradead.org/users/vkoul/slave-dma:
  dmaengine: tegra210-adma: Fix an error handling path in 'tegra_adma_probe()'
  dmaengine: ti: k3-udma: Fix TR mode flags for slave_sg and memcpy
  dmaengine: zynqmp_dma: Move list_del inside zynqmp_dma_free_descriptor.
  dmaengine: dmatest: Restore default for channel
  dmaengine: idxd: fix interrupt completion after unmasking
  dmaengine: owl: Use correct lock in owl_dma_get_pchan()
parents 57f1b0cf 3a5fd0db
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -1166,10 +1166,11 @@ static int dmatest_run_set(const char *val, const struct kernel_param *kp)
		mutex_unlock(&info->lock);
		return ret;
	} else if (dmatest_run) {
		if (is_threaded_test_pending(info))
		if (!is_threaded_test_pending(info)) {
			pr_info("No channels configured, continue with any\n");
			add_threaded_test(info);
		}
		start_threaded_tests(info);
		else
			pr_info("Could not start test, no channels configured\n");
	} else {
		stop_threaded_test(info);
	}
+7 −0
Original line number Diff line number Diff line
@@ -62,6 +62,13 @@ int idxd_unmask_msix_vector(struct idxd_device *idxd, int vec_id)
	perm.ignore = 0;
	iowrite32(perm.bits, idxd->reg_base + offset);

	/*
	 * A readback from the device ensures that any previously generated
	 * completion record writes are visible to software based on PCI
	 * ordering rules.
	 */
	perm.bits = ioread32(idxd->reg_base + offset);

	return 0;
}

+19 −7
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ static int irq_process_pending_llist(struct idxd_irq_entry *irq_entry,
	struct llist_node *head;
	int queued = 0;

	*processed = 0;
	head = llist_del_all(&irq_entry->pending_llist);
	if (!head)
		return 0;
@@ -197,6 +198,7 @@ static int irq_process_work_list(struct idxd_irq_entry *irq_entry,
	struct list_head *node, *next;
	int queued = 0;

	*processed = 0;
	if (list_empty(&irq_entry->work_list))
		return 0;

@@ -218,10 +220,9 @@ static int irq_process_work_list(struct idxd_irq_entry *irq_entry,
	return queued;
}

irqreturn_t idxd_wq_thread(int irq, void *data)
static int idxd_desc_process(struct idxd_irq_entry *irq_entry)
{
	struct idxd_irq_entry *irq_entry = data;
	int rc, processed = 0, retry = 0;
	int rc, processed, total = 0;

	/*
	 * There are two lists we are processing. The pending_llist is where
@@ -244,15 +245,26 @@ irqreturn_t idxd_wq_thread(int irq, void *data)
	 */
	do {
		rc = irq_process_work_list(irq_entry, &processed);
		if (rc != 0) {
			retry++;
		total += processed;
		if (rc != 0)
			continue;
		}

		rc = irq_process_pending_llist(irq_entry, &processed);
	} while (rc != 0 && retry != 10);
		total += processed;
	} while (rc != 0);

	return total;
}

irqreturn_t idxd_wq_thread(int irq, void *data)
{
	struct idxd_irq_entry *irq_entry = data;
	int processed;

	processed = idxd_desc_process(irq_entry);
	idxd_unmask_msix_vector(irq_entry->idxd, irq_entry->id);
	/* catch anything unprocessed after unmasking */
	processed += idxd_desc_process(irq_entry);

	if (processed == 0)
		return IRQ_NONE;
+3 −5
Original line number Diff line number Diff line
@@ -175,13 +175,11 @@ struct owl_dma_txd {
 * @id: physical index to this channel
 * @base: virtual memory base for the dma channel
 * @vchan: the virtual channel currently being served by this physical channel
 * @lock: a lock to use when altering an instance of this struct
 */
struct owl_dma_pchan {
	u32			id;
	void __iomem		*base;
	struct owl_dma_vchan	*vchan;
	spinlock_t		lock;
};

/**
@@ -437,14 +435,14 @@ static struct owl_dma_pchan *owl_dma_get_pchan(struct owl_dma *od,
	for (i = 0; i < od->nr_pchans; i++) {
		pchan = &od->pchans[i];

		spin_lock_irqsave(&pchan->lock, flags);
		spin_lock_irqsave(&od->lock, flags);
		if (!pchan->vchan) {
			pchan->vchan = vchan;
			spin_unlock_irqrestore(&pchan->lock, flags);
			spin_unlock_irqrestore(&od->lock, flags);
			break;
		}

		spin_unlock_irqrestore(&pchan->lock, flags);
		spin_unlock_irqrestore(&od->lock, flags);
	}

	return pchan;
+1 −1
Original line number Diff line number Diff line
@@ -900,7 +900,7 @@ static int tegra_adma_probe(struct platform_device *pdev)
	ret = dma_async_device_register(&tdma->dma_dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "ADMA registration failed: %d\n", ret);
		goto irq_dispose;
		goto rpm_put;
	}

	ret = of_dma_controller_register(pdev->dev.of_node,
Loading