Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
0004  *
0005  * @File    ctimap.c
0006  *
0007  * @Brief
0008  * This file contains the implementation of generic input mapper operations
0009  * for input mapper management.
0010  *
0011  * @Author  Liu Chun
0012  * @Date    May 23 2008
0013  */
0014 
0015 #include "ctimap.h"
0016 #include <linux/slab.h>
0017 
0018 int input_mapper_add(struct list_head *mappers, struct imapper *entry,
0019              int (*map_op)(void *, struct imapper *), void *data)
0020 {
0021     struct list_head *pos, *pre, *head;
0022     struct imapper *pre_ent, *pos_ent;
0023 
0024     head = mappers;
0025 
0026     if (list_empty(head)) {
0027         entry->next = entry->addr;
0028         map_op(data, entry);
0029         list_add(&entry->list, head);
0030         return 0;
0031     }
0032 
0033     list_for_each(pos, head) {
0034         pos_ent = list_entry(pos, struct imapper, list);
0035         if (pos_ent->slot > entry->slot) {
0036             /* found a position in list */
0037             break;
0038         }
0039     }
0040 
0041     if (pos != head) {
0042         pre = pos->prev;
0043         if (pre == head)
0044             pre = head->prev;
0045 
0046         __list_add(&entry->list, pos->prev, pos);
0047     } else {
0048         pre = head->prev;
0049         pos = head->next;
0050         list_add_tail(&entry->list, head);
0051     }
0052 
0053     pre_ent = list_entry(pre, struct imapper, list);
0054     pos_ent = list_entry(pos, struct imapper, list);
0055 
0056     entry->next = pos_ent->addr;
0057     map_op(data, entry);
0058     pre_ent->next = entry->addr;
0059     map_op(data, pre_ent);
0060 
0061     return 0;
0062 }
0063 
0064 int input_mapper_delete(struct list_head *mappers, struct imapper *entry,
0065              int (*map_op)(void *, struct imapper *), void *data)
0066 {
0067     struct list_head *next, *pre, *head;
0068     struct imapper *pre_ent, *next_ent;
0069 
0070     head = mappers;
0071 
0072     if (list_empty(head))
0073         return 0;
0074 
0075     pre = (entry->list.prev == head) ? head->prev : entry->list.prev;
0076     next = (entry->list.next == head) ? head->next : entry->list.next;
0077 
0078     if (pre == &entry->list) {
0079         /* entry is the only one node in mappers list */
0080         entry->next = entry->addr = entry->user = entry->slot = 0;
0081         map_op(data, entry);
0082         list_del(&entry->list);
0083         return 0;
0084     }
0085 
0086     pre_ent = list_entry(pre, struct imapper, list);
0087     next_ent = list_entry(next, struct imapper, list);
0088 
0089     pre_ent->next = next_ent->addr;
0090     map_op(data, pre_ent);
0091     list_del(&entry->list);
0092 
0093     return 0;
0094 }
0095 
0096 void free_input_mapper_list(struct list_head *head)
0097 {
0098     struct imapper *entry;
0099     struct list_head *pos;
0100 
0101     while (!list_empty(head)) {
0102         pos = head->next;
0103         list_del(pos);
0104         entry = list_entry(pos, struct imapper, list);
0105         kfree(entry);
0106     }
0107 }
0108