2 * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
4 * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
6 * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
32 static inline int alloc_fifo(struct fifo_struct *fifo, size_t sz)
34 if ((fifo->buf = kmalloc(sz, GFP_KERNEL)) == NULL) {
44 static inline int init_fifo(struct fifo_struct *fifo, size_t sz)
46 spin_lock_init(&fifo->lock);
47 return alloc_fifo(fifo, sz);
50 static inline void free_fifo(struct fifo_struct *fifo)
52 spin_lock(&fifo->lock);
53 if (fifo->buf == NULL) {
54 spin_unlock(&fifo->lock);
61 spin_unlock(&fifo->lock);
64 static inline void flush_fifo(struct fifo_struct *fifo)
66 spin_lock(&fifo->lock);
69 spin_unlock(&fifo->lock);
72 #define fifo_empty(fifo) ((fifo)->cnt == 0)
74 static inline int realloc_fifo(struct fifo_struct *fifo, size_t sz)
78 spin_lock(&fifo->lock);
79 if (!fifo_empty(fifo)) {
89 ret = alloc_fifo(fifo, sz);
92 spin_unlock(&fifo->lock);
96 static inline void write_word_to_fifo(struct fifo_struct *fifo, u16 word)
98 spin_lock(&fifo->lock);
99 *(u16 *)&fifo->buf[fifo->wp] = word;
100 if ((fifo->wp += 2) == fifo->sz)
102 if ((fifo->cnt += 2) > fifo->sz)
103 fifo->cnt = fifo->sz;
104 spin_unlock(&fifo->lock);
110 * [*******----------*************]
112 * <----------------------------> sz = 30
113 * <-----> <-----------> cnt = 20
116 * <-> <-----------> count = 16
117 * <-----------> cnt1 = 13
121 * [---****-----------------------]
124 static inline ssize_t copy_to_user_fm_fifo(char *dst, struct fifo_struct *fifo,
130 /* fifo size can be zero */
134 spin_lock(&fifo->lock);
135 if (count > fifo->cnt)
138 if ((rp = fifo->wp - fifo->cnt) >= 0) {
139 /* valid area is straight */
140 if (copy_to_user(dst, &fifo->buf[rp], count)) {
148 /* requested area is straight */
149 if (copy_to_user(dst, &fifo->buf[rp], count)) {
154 if (copy_to_user(dst, &fifo->buf[rp], cnt1)) {
158 if (copy_to_user(dst+cnt1, fifo->buf, count-cnt1)) {
168 spin_unlock(&fifo->lock);