1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. 4 * 5 * @File ctimap.c 6 * 7 * @Brief 8 * This file contains the implementation of generic input mapper operations 9 * for input mapper management. 10 * 11 * @Author Liu Chun 12 * @Date May 23 2008 13 */ 14 15 #include "ctimap.h" 16 #include <linux/slab.h> 17 18 int input_mapper_add(struct list_head *mappers, struct imapper *entry, 19 int (*map_op)(void *, struct imapper *), void *data) 20 { 21 struct list_head *pos, *pre, *head; 22 struct imapper *pre_ent, *pos_ent; 23 24 head = mappers; 25 26 if (list_empty(head)) { 27 entry->next = entry->addr; 28 map_op(data, entry); 29 list_add(&entry->list, head); 30 return 0; 31 } 32 33 list_for_each(pos, head) { 34 pos_ent = list_entry(pos, struct imapper, list); 35 if (pos_ent->slot > entry->slot) { 36 /* found a position in list */ 37 break; 38 } 39 } 40 41 if (pos != head) { 42 pre = pos->prev; 43 if (pre == head) 44 pre = head->prev; 45 46 __list_add(&entry->list, pos->prev, pos); 47 } else { 48 pre = head->prev; 49 pos = head->next; 50 list_add_tail(&entry->list, head); 51 } 52 53 pre_ent = list_entry(pre, struct imapper, list); 54 pos_ent = list_entry(pos, struct imapper, list); 55 56 entry->next = pos_ent->addr; 57 map_op(data, entry); 58 pre_ent->next = entry->addr; 59 map_op(data, pre_ent); 60 61 return 0; 62 } 63 64 int input_mapper_delete(struct list_head *mappers, struct imapper *entry, 65 int (*map_op)(void *, struct imapper *), void *data) 66 { 67 struct list_head *next, *pre, *head; 68 struct imapper *pre_ent, *next_ent; 69 70 head = mappers; 71 72 if (list_empty(head)) 73 return 0; 74 75 pre = (entry->list.prev == head) ? head->prev : entry->list.prev; 76 next = (entry->list.next == head) ? head->next : entry->list.next; 77 78 if (pre == &entry->list) { 79 /* entry is the only one node in mappers list */ 80 entry->next = entry->addr = entry->user = entry->slot = 0; 81 map_op(data, entry); 82 list_del(&entry->list); 83 return 0; 84 } 85 86 pre_ent = list_entry(pre, struct imapper, list); 87 next_ent = list_entry(next, struct imapper, list); 88 89 pre_ent->next = next_ent->addr; 90 map_op(data, pre_ent); 91 list_del(&entry->list); 92 93 return 0; 94 } 95 96 void free_input_mapper_list(struct list_head *head) 97 { 98 struct imapper *entry; 99 struct list_head *pos; 100 101 while (!list_empty(head)) { 102 pos = head->next; 103 list_del(pos); 104 entry = list_entry(pos, struct imapper, list); 105 kfree(entry); 106 } 107 } 108 109