Unverified Commit 7bbe9ba2 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!14041 sdma-dae: bugfix of channel operation

Merge Pull Request from: @zhang-yuyang-0821 
 
1. fix channel ida management.
2. change channel reset logic.
3. change memory alloc flag to GFP_ATOMIC. 
 
Link:https://gitee.com/openeuler/kernel/pulls/14041

 

Reviewed-by: default avatarLi Nan <linan122@huawei.com>
Signed-off-by: default avatarLi Nan <linan122@huawei.com>
parents 0ddd395e 4189703c
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -124,14 +124,16 @@ static int sdma_add_ida_ref(struct hisi_sdma_channel *pchannel, int ida)
	spin_lock(&pchannel->owner_chn_lock);
	entry = sdma_search_ida_ref(pchannel, ida);
	if (entry == NULL) {
		entry = kzalloc(sizeof(struct hisi_sdma_channel_node), GFP_KERNEL);
		entry = kzalloc(sizeof(struct hisi_sdma_channel_node), GFP_ATOMIC);
		if (entry == NULL) {
			spin_unlock(&pchannel->owner_chn_lock);
			return -ENOMEM;
		}
		entry->ida = ida;
		entry->ref = 1;
		hash_add(pchannel->sdma_ida_ht, &entry->node, entry->ida);
	}
	} else
		entry->ref++;
	spin_unlock(&pchannel->owner_chn_lock);
	return 0;
}
@@ -143,8 +145,11 @@ static bool sdma_del_ida_ref(struct hisi_sdma_channel *pchannel, int ida)
	spin_lock(&pchannel->owner_chn_lock);
	entry = sdma_search_ida_ref(pchannel, ida);
	if (entry != NULL) {
		entry->ref--;
		if (entry->ref == 0) {
			hash_del(&entry->node);
			kfree(entry);
		}
	} else {
		spin_unlock(&pchannel->owner_chn_lock);
		return false;
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ struct hisi_sdma_channel {

struct hisi_sdma_channel_node {
	int ida;
	u32 ref;
	struct hlist_node node;
};

+7 −7
Original line number Diff line number Diff line
@@ -89,18 +89,18 @@ static void sdma_channel_init(struct hisi_sdma_channel *pchan)

static void sdma_channel_reset_sq_cq(struct hisi_sdma_channel *pchan)
{
	u32 sq_head, sq_tail, cq_head, cq_tail;
	u32 cq_head, cq_tail;

	sq_head = sdma_channel_get_sq_head(pchan);
	sq_tail = sdma_channel_get_sq_tail(pchan);
	cq_head = sdma_channel_get_cq_head(pchan);
	cq_tail = sdma_channel_get_cq_tail(pchan);

	if (sq_head != sq_tail)
		sdma_channel_set_sq_tail(pchan, sq_head);

	if (cq_head != cq_tail)
	while (cq_head != cq_tail) {
		sdma_channel_set_cq_head(pchan, cq_tail);
		msleep(HISI_SDMA_FSM_INTERVAL);

		cq_head = sdma_channel_get_cq_head(pchan);
		cq_tail = sdma_channel_get_cq_tail(pchan);
	}
}

static void sdma_channel_reset(struct hisi_sdma_channel *pchan)