Commit dde48d89 authored by Tudor Ambarus's avatar Tudor Ambarus Committed by sanglipeng
Browse files

dmaengine: at_hdmac: Fix descriptor handling when issuing it to hardware

stable inclusion
from stable-v5.10.155
commit 6be4ab08c8637bcea930ee399bd1001d2250b168
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7M5F4

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=6be4ab08c8637bcea930ee399bd1001d2250b168



--------------------------------

commit ba242363 upstream.

As it was before, the descriptor was issued to the hardware without adding
it to the active (issued) list. This could result in a completion of other
descriptor, or/and in the descriptor never being completed.

Fixes: dc78baa2 ("dmaengine: at_hdmac: new driver for the Atmel AHB DMA Controller")
Reported-by: default avatarPeter Rosin <peda@axentia.se>
Signed-off-by: default avatarTudor Ambarus <tudor.ambarus@microchip.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/lkml/13c6c9a2-6db5-c3bf-349b-4c127ad3496a@axentia.se/


Acked-by: default avatarNicolas Ferre <nicolas.ferre@microchip.com>
Link: https://lore.kernel.org/r/20221025090306.297886-1-tudor.ambarus@microchip.com
Link: https://lore.kernel.org/r/20221025090306.297886-12-tudor.ambarus@microchip.com


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarsanglipeng <sanglipeng1@jd.com>
parent 7b221c5f
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -491,8 +491,11 @@ static void atc_advance_work(struct at_dma_chan *atchan)

	/* advance work */
	spin_lock_irqsave(&atchan->lock, flags);
	if (!list_empty(&atchan->active_list))
		atc_dostart(atchan, atc_first_active(atchan));
	if (!list_empty(&atchan->active_list)) {
		desc = atc_first_queued(atchan);
		list_move_tail(&desc->desc_node, &atchan->active_list);
		atc_dostart(atchan, desc);
	}
	spin_unlock_irqrestore(&atchan->lock, flags);
}

@@ -504,6 +507,7 @@ static void atc_advance_work(struct at_dma_chan *atchan)
static void atc_handle_error(struct at_dma_chan *atchan)
{
	struct at_desc *bad_desc;
	struct at_desc *desc;
	struct at_desc *child;
	unsigned long flags;

@@ -521,8 +525,11 @@ static void atc_handle_error(struct at_dma_chan *atchan)
	list_splice_init(&atchan->queue, atchan->active_list.prev);

	/* Try to restart the controller */
	if (!list_empty(&atchan->active_list))
		atc_dostart(atchan, atc_first_active(atchan));
	if (!list_empty(&atchan->active_list)) {
		desc = atc_first_queued(atchan);
		list_move_tail(&desc->desc_node, &atchan->active_list);
		atc_dostart(atchan, desc);
	}

	/*
	 * KERN_CRITICAL may seem harsh, but since this only happens