linux-brain/sound/pci/ctxfi/ctimap.c
Thomas Gleixner 5765e78e84 treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 364
Based on 1 normalized pattern(s):

  this source file is released under gpl v2 license no other versions
  see the copying file included in the main directory of this source
  distribution for the license terms and conditions

extracted by the scancode license scanner the SPDX license identifier

  GPL-2.0-only

has been chosen to replace the boilerplate/reference in 28 file(s).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Allison Randal <allison@lohutok.net>
Reviewed-by: Armijn Hemel <armijn@tjaldur.nl>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190531081035.780831265@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-05 17:37:09 +02:00

109 lines
2.3 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/**
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
*
* @File ctimap.c
*
* @Brief
* This file contains the implementation of generic input mapper operations
* for input mapper management.
*
* @Author Liu Chun
* @Date May 23 2008
*/
#include "ctimap.h"
#include <linux/slab.h>
int input_mapper_add(struct list_head *mappers, struct imapper *entry,
int (*map_op)(void *, struct imapper *), void *data)
{
struct list_head *pos, *pre, *head;
struct imapper *pre_ent, *pos_ent;
head = mappers;
if (list_empty(head)) {
entry->next = entry->addr;
map_op(data, entry);
list_add(&entry->list, head);
return 0;
}
list_for_each(pos, head) {
pos_ent = list_entry(pos, struct imapper, list);
if (pos_ent->slot > entry->slot) {
/* found a position in list */
break;
}
}
if (pos != head) {
pre = pos->prev;
if (pre == head)
pre = head->prev;
__list_add(&entry->list, pos->prev, pos);
} else {
pre = head->prev;
pos = head->next;
list_add_tail(&entry->list, head);
}
pre_ent = list_entry(pre, struct imapper, list);
pos_ent = list_entry(pos, struct imapper, list);
entry->next = pos_ent->addr;
map_op(data, entry);
pre_ent->next = entry->addr;
map_op(data, pre_ent);
return 0;
}
int input_mapper_delete(struct list_head *mappers, struct imapper *entry,
int (*map_op)(void *, struct imapper *), void *data)
{
struct list_head *next, *pre, *head;
struct imapper *pre_ent, *next_ent;
head = mappers;
if (list_empty(head))
return 0;
pre = (entry->list.prev == head) ? head->prev : entry->list.prev;
next = (entry->list.next == head) ? head->next : entry->list.next;
if (pre == &entry->list) {
/* entry is the only one node in mappers list */
entry->next = entry->addr = entry->user = entry->slot = 0;
map_op(data, entry);
list_del(&entry->list);
return 0;
}
pre_ent = list_entry(pre, struct imapper, list);
next_ent = list_entry(next, struct imapper, list);
pre_ent->next = next_ent->addr;
map_op(data, pre_ent);
list_del(&entry->list);
return 0;
}
void free_input_mapper_list(struct list_head *head)
{
struct imapper *entry;
struct list_head *pos;
while (!list_empty(head)) {
pos = head->next;
list_del(pos);
entry = list_entry(pos, struct imapper, list);
kfree(entry);
}
}