1*5765e78eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 28cc72361SWai Yew CHAY /** 38cc72361SWai Yew CHAY * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. 48cc72361SWai Yew CHAY * 58cc72361SWai Yew CHAY * @File ctimap.c 68cc72361SWai Yew CHAY * 78cc72361SWai Yew CHAY * @Brief 88cc72361SWai Yew CHAY * This file contains the implementation of generic input mapper operations 98cc72361SWai Yew CHAY * for input mapper management. 108cc72361SWai Yew CHAY * 118cc72361SWai Yew CHAY * @Author Liu Chun 128cc72361SWai Yew CHAY * @Date May 23 2008 138cc72361SWai Yew CHAY */ 148cc72361SWai Yew CHAY 158cc72361SWai Yew CHAY #include "ctimap.h" 168cc72361SWai Yew CHAY #include <linux/slab.h> 178cc72361SWai Yew CHAY 188cc72361SWai Yew CHAY int input_mapper_add(struct list_head *mappers, struct imapper *entry, 198cc72361SWai Yew CHAY int (*map_op)(void *, struct imapper *), void *data) 208cc72361SWai Yew CHAY { 218cc72361SWai Yew CHAY struct list_head *pos, *pre, *head; 228cc72361SWai Yew CHAY struct imapper *pre_ent, *pos_ent; 238cc72361SWai Yew CHAY 248cc72361SWai Yew CHAY head = mappers; 258cc72361SWai Yew CHAY 268cc72361SWai Yew CHAY if (list_empty(head)) { 278cc72361SWai Yew CHAY entry->next = entry->addr; 288cc72361SWai Yew CHAY map_op(data, entry); 298cc72361SWai Yew CHAY list_add(&entry->list, head); 308cc72361SWai Yew CHAY return 0; 318cc72361SWai Yew CHAY } 328cc72361SWai Yew CHAY 338cc72361SWai Yew CHAY list_for_each(pos, head) { 348cc72361SWai Yew CHAY pos_ent = list_entry(pos, struct imapper, list); 358cc72361SWai Yew CHAY if (pos_ent->slot > entry->slot) { 368cc72361SWai Yew CHAY /* found a position in list */ 378cc72361SWai Yew CHAY break; 388cc72361SWai Yew CHAY } 398cc72361SWai Yew CHAY } 408cc72361SWai Yew CHAY 418cc72361SWai Yew CHAY if (pos != head) { 428cc72361SWai Yew CHAY pre = pos->prev; 438cc72361SWai Yew CHAY if (pre == head) 448cc72361SWai Yew CHAY pre = head->prev; 458cc72361SWai Yew CHAY 468cc72361SWai Yew CHAY __list_add(&entry->list, pos->prev, pos); 478cc72361SWai Yew CHAY } else { 488cc72361SWai Yew CHAY pre = head->prev; 498cc72361SWai Yew CHAY pos = head->next; 508cc72361SWai Yew CHAY list_add_tail(&entry->list, head); 518cc72361SWai Yew CHAY } 528cc72361SWai Yew CHAY 538cc72361SWai Yew CHAY pre_ent = list_entry(pre, struct imapper, list); 548cc72361SWai Yew CHAY pos_ent = list_entry(pos, struct imapper, list); 558cc72361SWai Yew CHAY 568cc72361SWai Yew CHAY entry->next = pos_ent->addr; 578cc72361SWai Yew CHAY map_op(data, entry); 588cc72361SWai Yew CHAY pre_ent->next = entry->addr; 598cc72361SWai Yew CHAY map_op(data, pre_ent); 608cc72361SWai Yew CHAY 618cc72361SWai Yew CHAY return 0; 628cc72361SWai Yew CHAY } 638cc72361SWai Yew CHAY 648cc72361SWai Yew CHAY int input_mapper_delete(struct list_head *mappers, struct imapper *entry, 658cc72361SWai Yew CHAY int (*map_op)(void *, struct imapper *), void *data) 668cc72361SWai Yew CHAY { 678cc72361SWai Yew CHAY struct list_head *next, *pre, *head; 688cc72361SWai Yew CHAY struct imapper *pre_ent, *next_ent; 698cc72361SWai Yew CHAY 708cc72361SWai Yew CHAY head = mappers; 718cc72361SWai Yew CHAY 728cc72361SWai Yew CHAY if (list_empty(head)) 738cc72361SWai Yew CHAY return 0; 748cc72361SWai Yew CHAY 758cc72361SWai Yew CHAY pre = (entry->list.prev == head) ? head->prev : entry->list.prev; 768cc72361SWai Yew CHAY next = (entry->list.next == head) ? head->next : entry->list.next; 778cc72361SWai Yew CHAY 788cc72361SWai Yew CHAY if (pre == &entry->list) { 798cc72361SWai Yew CHAY /* entry is the only one node in mappers list */ 808cc72361SWai Yew CHAY entry->next = entry->addr = entry->user = entry->slot = 0; 818cc72361SWai Yew CHAY map_op(data, entry); 828cc72361SWai Yew CHAY list_del(&entry->list); 838cc72361SWai Yew CHAY return 0; 848cc72361SWai Yew CHAY } 858cc72361SWai Yew CHAY 868cc72361SWai Yew CHAY pre_ent = list_entry(pre, struct imapper, list); 878cc72361SWai Yew CHAY next_ent = list_entry(next, struct imapper, list); 888cc72361SWai Yew CHAY 898cc72361SWai Yew CHAY pre_ent->next = next_ent->addr; 908cc72361SWai Yew CHAY map_op(data, pre_ent); 918cc72361SWai Yew CHAY list_del(&entry->list); 928cc72361SWai Yew CHAY 938cc72361SWai Yew CHAY return 0; 948cc72361SWai Yew CHAY } 958cc72361SWai Yew CHAY 968cc72361SWai Yew CHAY void free_input_mapper_list(struct list_head *head) 978cc72361SWai Yew CHAY { 98514eef9cSTakashi Iwai struct imapper *entry; 99514eef9cSTakashi Iwai struct list_head *pos; 1008cc72361SWai Yew CHAY 1018cc72361SWai Yew CHAY while (!list_empty(head)) { 1028cc72361SWai Yew CHAY pos = head->next; 1038cc72361SWai Yew CHAY list_del(pos); 1048cc72361SWai Yew CHAY entry = list_entry(pos, struct imapper, list); 1058cc72361SWai Yew CHAY kfree(entry); 1068cc72361SWai Yew CHAY } 1078cc72361SWai Yew CHAY } 1088cc72361SWai Yew CHAY 109