178 lines
3.3 KiB
C
Executable file
178 lines
3.3 KiB
C
Executable file
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Samsung Exynos SoC series dsp driver
|
|
*
|
|
* Copyright (c) 2019 Samsung Electronics Co., Ltd.
|
|
* http://www.samsung.com/
|
|
*/
|
|
|
|
#include "dl/dsp-list.h"
|
|
|
|
void dsp_list_head_init(struct dsp_list_head *head)
|
|
{
|
|
head->num = 0;
|
|
head->next = NULL;
|
|
head->prev = NULL;
|
|
}
|
|
|
|
void dsp_list_node_init(struct dsp_list_node *node)
|
|
{
|
|
node->next = NULL;
|
|
node->prev = NULL;
|
|
}
|
|
|
|
void dsp_list_node_push_back(struct dsp_list_head *head,
|
|
struct dsp_list_node *node)
|
|
{
|
|
head->num++;
|
|
|
|
if (head->prev == NULL)
|
|
head->next = node;
|
|
else {
|
|
head->prev->next = node;
|
|
node->prev = head->prev;
|
|
}
|
|
|
|
head->prev = node;
|
|
}
|
|
|
|
void dsp_list_node_insert_back(struct dsp_list_head *head,
|
|
struct dsp_list_node *loc, struct dsp_list_node *node)
|
|
{
|
|
head->num++;
|
|
|
|
if (loc->next == NULL)
|
|
head->prev = node;
|
|
else
|
|
loc->next->prev = node;
|
|
|
|
node->prev = loc;
|
|
node->next = loc->next;
|
|
loc->next = node;
|
|
}
|
|
|
|
void dsp_list_node_remove(struct dsp_list_head *head,
|
|
struct dsp_list_node *node)
|
|
{
|
|
head->num--;
|
|
|
|
if (node->prev == NULL)
|
|
head->next = node->next;
|
|
else
|
|
node->prev->next = node->next;
|
|
|
|
if (node->next == NULL)
|
|
head->prev = node->prev;
|
|
else
|
|
node->next->prev = node->prev;
|
|
}
|
|
|
|
void dsp_list_node_swap(struct dsp_list_head *head,
|
|
struct dsp_list_node *node1,
|
|
struct dsp_list_node *node2)
|
|
{
|
|
struct dsp_list_node *swap_tmp;
|
|
|
|
if (node1->next == node2) {
|
|
swap_tmp = node1->prev;
|
|
node1->prev = node2;
|
|
node2->prev = swap_tmp;
|
|
|
|
swap_tmp = node2->next;
|
|
node2->next = node1;
|
|
node1->next = swap_tmp;
|
|
} else if (node2->next == node1) {
|
|
swap_tmp = node1->next;
|
|
node1->next = node2;
|
|
node2->next = swap_tmp;
|
|
|
|
swap_tmp = node2->prev;
|
|
node2->prev = node1;
|
|
node1->prev = swap_tmp;
|
|
} else {
|
|
swap_tmp = node1->next;
|
|
node1->next = node2->next;
|
|
node2->next = swap_tmp;
|
|
|
|
swap_tmp = node1->prev;
|
|
node1->prev = node2->prev;
|
|
node2->prev = swap_tmp;
|
|
}
|
|
|
|
if (!node1->prev)
|
|
head->next = node1;
|
|
else
|
|
node1->prev->next = node1;
|
|
|
|
if (!node1->next)
|
|
head->prev = node1;
|
|
else
|
|
node1->next->prev = node1;
|
|
|
|
if (!node2->prev)
|
|
head->next = node2;
|
|
else
|
|
node2->prev->next = node2;
|
|
|
|
if (!node2->next)
|
|
head->prev = node2;
|
|
else
|
|
node2->next->prev = node2;
|
|
}
|
|
|
|
void dsp_list_merge(struct dsp_list_head *head,
|
|
struct dsp_list_head *head1,
|
|
struct dsp_list_head *head2)
|
|
{
|
|
head1->prev->next = head2->next;
|
|
head2->next->prev = head1->prev;
|
|
head->prev = head2->prev;
|
|
head->next = head1->next;
|
|
head->num = head1->num + head2->num;
|
|
}
|
|
|
|
int dsp_list_is_empty(struct dsp_list_head *head)
|
|
{
|
|
if (head->next == NULL && head->prev == NULL)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
void dsp_list_sort(struct dsp_list_head *head,
|
|
dsp_list_compare_func func)
|
|
{
|
|
int swap_ck = 1;
|
|
struct dsp_list_node *node;
|
|
|
|
while (swap_ck) {
|
|
swap_ck = 0;
|
|
for (node = head->next; node != NULL && node->next != NULL;) {
|
|
if (func(node, node->next) < 0) {
|
|
dsp_list_node_swap(head, node, node->next);
|
|
swap_ck = 1;
|
|
} else
|
|
node = node->next;
|
|
}
|
|
}
|
|
}
|
|
|
|
void dsp_list_unique(struct dsp_list_head *head,
|
|
struct dsp_list_head *remove,
|
|
dsp_list_compare_func func)
|
|
{
|
|
struct dsp_list_node *node, *next;
|
|
|
|
dsp_list_for_each(node, head) {
|
|
dsp_list_for_each(next, node) {
|
|
struct dsp_list_node *prev = next->prev;
|
|
|
|
if (func(node, next) == 0) {
|
|
dsp_list_node_remove(head, next);
|
|
dsp_list_node_init(next);
|
|
dsp_list_node_push_back(remove, next);
|
|
next = prev;
|
|
}
|
|
}
|
|
}
|
|
}
|