From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 23749518132; Wed, 30 Sep 2026 17:11:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790788318; cv=none; b=iHabfY7PjUOubMeq7OsMO6eWi6JyVUqhmnhUybHt4GrJ7QWuftP34b4RrP6weA6Xg+NusJSN9SucraEgSXBVlvKohEJcGee25M9IhhvwPSEsodJCeNUqWUF2sCCIi8AfvQ6+66M1qPTW+UwsW3d5z7lLmMyrXtvai7/qQ8cfNHg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790788318; c=relaxed/simple; bh=MahgyvY93xTfca7sUS5ZmyYUZkJrEXJB8OWFsb1/GlI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ayUDoLSfEFlVlyNrwiLe9U//SGs4RfAqwnNtLj+ODvIWkGEGaq8819HeVbLDjvUR/mjLo3RXK+rq0eUw+SY0qRg0hchR18FuaaLa7b1sgQRdQRZZAcoPyc5RZnvMyV1w7Gx9YwAzjp0zvEFKlGmEFipmSoIc3ZtkuPF09X0ara0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=YX3gCxrG; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="YX3gCxrG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7F3BD1F000FF; Wed, 30 Sep 2026 17:11:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1790788317; bh=2HWUkWhKIdKjwORu+6gVfageScnUiHOUw4wSfY+HTg0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=YX3gCxrGogBivlHIediME6bwTr2COLJBmyJmrq0oCncG/ikgFxScplOCXMawlNnd+ x0Cb8vCfkIBDeK5xhbhzJw/WFoTGAtNKAlkf+goCLHuBqEpePOgeENBOTmret9OlV7 j+6NTGmxscPCPpZG6Z3sicB+eOwQ9sFsMzm3xYSc= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Alex Bereza , Frank Li , Suraj Gupta , Vinod Koul , Sasha Levin Subject: [PATCH 6.12 082/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor chain after cyclic DMA Date: Wed, 30 Sep 2026 17:16:33 +0200 Message-ID: <20260930152416.510398956@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260930152414.738996857@linuxfoundation.org> References: <20260930152414.738996857@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Alex Bereza [ Upstream commit 7ed1e3070c9b4bbd67d5519e14711038dd53ab13 ] Using the DMA in cyclic mode modifies the hardware buffer descriptor chain in xilinx_dma_prep_dma_cyclic so that the last descriptor used by the cyclic transfer points back to the first descriptor, but it never restores the original descriptor ring. This breaks using non-cyclic mode after cyclic mode with an error like: xilinx-vdma 86000000.dma: Channel 00000000354d5c8d has errors 100, cdr 6de40000 tdr 6de40400 The only way to get out of this error state is to rebuild the hardware buffer descriptor ring by releasing and re-acquiring the channel. Fix using non-cyclic mode after cyclic mode by always restoring the original buffer descriptor ring in the same manner as it is set up by xilinx_dma_alloc_chan_resources(). Fixes: 23059408b6a3 ("dmaengine: xilinx_dma: Fix race condition in the driver for multiple descriptor scenario") Signed-off-by: Alex Bereza Reviewed-by: Frank Li Reviewed-by: Suraj Gupta Link: https://patch.msgid.link/20260817-fix-hw-buf-desc-after-cyclic-mode-v1-1-1fe47e701d6c@bereza.email Link: https://patch.msgid.link/20260818-fix-hw-buf-desc-after-cyclic-mode-v2-1-530ff44c6a81@bereza.email Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/xilinx/xilinx_dma.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 29ff6c8082fb1..4a89ad8c90a34 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -753,15 +753,25 @@ xilinx_aximcdma_alloc_tx_segment(struct xilinx_dma_chan *chan) return segment; } -static void xilinx_dma_clean_hw_desc(struct xilinx_axidma_desc_hw *hw) +static void xilinx_dma_clean_hw_desc(struct xilinx_dma_chan *chan, + struct xilinx_axidma_tx_segment *segment) { - u32 next_desc = hw->next_desc; - u32 next_desc_msb = hw->next_desc_msb; + dma_addr_t next; + u32 i; - memset(hw, 0, sizeof(struct xilinx_axidma_desc_hw)); + /* + * Restore the buffer descriptor's next descriptor pointer to the value + * set up in xilinx_dma_alloc_chan_resources(). Otherwise using the DMA + * in cyclic mode leaves the next descriptor pointer altered and + * prevents subsequent non-cyclic transfers. + */ + i = segment - chan->seg_v; + next = chan->seg_p + + sizeof(*chan->seg_v) * ((i + 1) % XILINX_DMA_NUM_DESCS); - hw->next_desc = next_desc; - hw->next_desc_msb = next_desc_msb; + memset(&segment->hw, 0, sizeof(segment->hw)); + segment->hw.next_desc = lower_32_bits(next); + segment->hw.next_desc_msb = upper_32_bits(next); } static void xilinx_mcdma_clean_hw_desc(struct xilinx_aximcdma_desc_hw *hw) @@ -783,7 +793,7 @@ static void xilinx_mcdma_clean_hw_desc(struct xilinx_aximcdma_desc_hw *hw) static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan, struct xilinx_axidma_tx_segment *segment) { - xilinx_dma_clean_hw_desc(&segment->hw); + xilinx_dma_clean_hw_desc(chan, segment); list_add_tail(&segment->node, &chan->free_seg_list); } -- 2.53.0