Commit 3439b2a8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull dmaengine fixes from Vinod Koul:
 "Driver fixes for:

   - stm32 dma residue calculation and chaining

   - stm32 mdma for setting inflight bytes, residue calculation and
     resume abort

   - channel request, channel enable and dma error in fsl_edma

   - runtime pm imbalance in ste_dma40 driver

   - deadlock fix in mediatek driver"

* tag 'dmaengine-fix-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine:
  dmaengine: fsl-edma: fix all channels requested when call fsl_edma3_xlate()
  dmaengine: stm32-dma: fix residue in case of MDMA chaining
  dmaengine: stm32-dma: fix stm32_dma_prep_slave_sg in case of MDMA chaining
  dmaengine: stm32-mdma: set in_flight_bytes in case CRQA flag is set
  dmaengine: stm32-mdma: use Link Address Register to compute residue
  dmaengine: stm32-mdma: abort resume if no ongoing transfer
  dmaengine: ste_dma40: Fix PM disable depth imbalance in d40_probe
  dmaengine: mediatek: Fix deadlock caused by synchronize_irq()
  dmaengine: idxd: use spin_lock_irqsave before wait_event_lock_irq
  dmaengine: fsl-edma: fix edma4 channel enable failure on second attempt
  dt-bindings: dmaengine: zynqmp_dma: add xlnx,bus-width required property
  dmaengine: fsl-dma: fix DMA error when enabling sg if 'DONE' bit is set
parents 7c367d8e 3fa53518
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@ description: |

maintainers:
  - Michael Tretter <m.tretter@pengutronix.de>
  - Harini Katakam <harini.katakam@amd.com>
  - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>

allOf:
  - $ref: ../dma-controller.yaml#
@@ -65,6 +67,7 @@ required:
  - interrupts
  - clocks
  - clock-names
  - xlnx,bus-width

additionalProperties: false

+22 −3
Original line number Diff line number Diff line
@@ -92,8 +92,14 @@ static void fsl_edma3_enable_request(struct fsl_edma_chan *fsl_chan)

	edma_writel_chreg(fsl_chan, val, ch_sbr);

	if (flags & FSL_EDMA_DRV_HAS_CHMUX)
	if (flags & FSL_EDMA_DRV_HAS_CHMUX) {
		/*
		 * ch_mux: With the exception of 0, attempts to write a value
		 * already in use will be forced to 0.
		 */
		if (!edma_readl_chreg(fsl_chan, ch_mux))
			edma_writel_chreg(fsl_chan, fsl_chan->srcid, ch_mux);
	}

	val = edma_readl_chreg(fsl_chan, ch_csr);
	val |= EDMA_V3_CH_CSR_ERQ;
@@ -448,12 +454,25 @@ static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,

	edma_write_tcdreg(fsl_chan, tcd->dlast_sga, dlast_sga);

	if (fsl_chan->is_sw) {
	csr = le16_to_cpu(tcd->csr);

	if (fsl_chan->is_sw) {
		csr |= EDMA_TCD_CSR_START;
		tcd->csr = cpu_to_le16(csr);
	}

	/*
	 * Must clear CHn_CSR[DONE] bit before enable TCDn_CSR[ESG] at EDMAv3
	 * eDMAv4 have not such requirement.
	 * Change MLINK need clear CHn_CSR[DONE] for both eDMAv3 and eDMAv4.
	 */
	if (((fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_CLEAR_DONE_E_SG) &&
		(csr & EDMA_TCD_CSR_E_SG)) ||
	    ((fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_CLEAR_DONE_E_LINK) &&
		(csr & EDMA_TCD_CSR_E_LINK)))
		edma_writel_chreg(fsl_chan, edma_readl_chreg(fsl_chan, ch_csr), ch_csr);


	edma_write_tcdreg(fsl_chan, tcd->csr, csr);
}

+13 −1
Original line number Diff line number Diff line
@@ -183,11 +183,23 @@ struct fsl_edma_desc {
#define FSL_EDMA_DRV_BUS_8BYTE		BIT(10)
#define FSL_EDMA_DRV_DEV_TO_DEV		BIT(11)
#define FSL_EDMA_DRV_ALIGN_64BYTE	BIT(12)
/* Need clean CHn_CSR DONE before enable TCD's ESG */
#define FSL_EDMA_DRV_CLEAR_DONE_E_SG	BIT(13)
/* Need clean CHn_CSR DONE before enable TCD's MAJORELINK */
#define FSL_EDMA_DRV_CLEAR_DONE_E_LINK	BIT(14)

#define FSL_EDMA_DRV_EDMA3	(FSL_EDMA_DRV_SPLIT_REG |	\
				 FSL_EDMA_DRV_BUS_8BYTE |	\
				 FSL_EDMA_DRV_DEV_TO_DEV |	\
				 FSL_EDMA_DRV_ALIGN_64BYTE)
				 FSL_EDMA_DRV_ALIGN_64BYTE |	\
				 FSL_EDMA_DRV_CLEAR_DONE_E_SG |	\
				 FSL_EDMA_DRV_CLEAR_DONE_E_LINK)

#define FSL_EDMA_DRV_EDMA4	(FSL_EDMA_DRV_SPLIT_REG |	\
				 FSL_EDMA_DRV_BUS_8BYTE |	\
				 FSL_EDMA_DRV_DEV_TO_DEV |	\
				 FSL_EDMA_DRV_ALIGN_64BYTE |	\
				 FSL_EDMA_DRV_CLEAR_DONE_E_LINK)

struct fsl_edma_drvdata {
	u32			dmamuxs; /* only used before v3 */
+5 −3
Original line number Diff line number Diff line
@@ -154,18 +154,20 @@ static struct dma_chan *fsl_edma3_xlate(struct of_phandle_args *dma_spec,
		fsl_chan = to_fsl_edma_chan(chan);
		i = fsl_chan - fsl_edma->chans;

		chan = dma_get_slave_channel(chan);
		chan->device->privatecnt++;
		fsl_chan->priority = dma_spec->args[1];
		fsl_chan->is_rxchan = dma_spec->args[2] & ARGS_RX;
		fsl_chan->is_remote = dma_spec->args[2] & ARGS_REMOTE;
		fsl_chan->is_multi_fifo = dma_spec->args[2] & ARGS_MULTI_FIFO;

		if (!b_chmux && i == dma_spec->args[0]) {
			chan = dma_get_slave_channel(chan);
			chan->device->privatecnt++;
			mutex_unlock(&fsl_edma->fsl_edma_mutex);
			return chan;
		} else if (b_chmux && !fsl_chan->srcid) {
			/* if controller support channel mux, choose a free channel */
			chan = dma_get_slave_channel(chan);
			chan->device->privatecnt++;
			fsl_chan->srcid = dma_spec->args[0];
			mutex_unlock(&fsl_edma->fsl_edma_mutex);
			return chan;
@@ -355,7 +357,7 @@ static struct fsl_edma_drvdata imx93_data3 = {
};

static struct fsl_edma_drvdata imx93_data4 = {
	.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA3,
	.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA4,
	.chreg_space_sz = 0x8000,
	.chreg_off = 0x10000,
	.setup_irq = fsl_edma3_irq_init,
+3 −2
Original line number Diff line number Diff line
@@ -477,6 +477,7 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand,
	union idxd_command_reg cmd;
	DECLARE_COMPLETION_ONSTACK(done);
	u32 stat;
	unsigned long flags;

	if (idxd_device_is_halted(idxd)) {
		dev_warn(&idxd->pdev->dev, "Device is HALTED!\n");
@@ -490,7 +491,7 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand,
	cmd.operand = operand;
	cmd.int_req = 1;

	spin_lock(&idxd->cmd_lock);
	spin_lock_irqsave(&idxd->cmd_lock, flags);
	wait_event_lock_irq(idxd->cmd_waitq,
			    !test_bit(IDXD_FLAG_CMD_RUNNING, &idxd->flags),
			    idxd->cmd_lock);
@@ -507,7 +508,7 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand,
	 * After command submitted, release lock and go to sleep until
	 * the command completes via interrupt.
	 */
	spin_unlock(&idxd->cmd_lock);
	spin_unlock_irqrestore(&idxd->cmd_lock, flags);
	wait_for_completion(&done);
	stat = ioread32(idxd->reg_base + IDXD_CMDSTS_OFFSET);
	spin_lock(&idxd->cmd_lock);
Loading