2 * linux/arch/arm/mach-omap/dsp/fifo.h
4 * FIFO buffer operators
6 * Copyright (C) 2002-2005 Nokia Corporation
8 * Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * 2005/02/24: DSP Gateway version 3.3
35 static inline int alloc_fifo(struct fifo_struct *fifo, size_t sz)
37 if ((fifo->buf = kmalloc(sz, GFP_KERNEL)) == NULL) {
47 static inline int init_fifo(struct fifo_struct *fifo, size_t sz)
49 spin_lock_init(&fifo->lock);
50 return alloc_fifo(fifo, sz);
53 static inline void free_fifo(struct fifo_struct *fifo)
55 spin_lock(&fifo->lock);
56 if (fifo->buf == NULL)
62 spin_unlock(&fifo->lock);
65 static inline void flush_fifo(struct fifo_struct *fifo)
67 spin_lock(&fifo->lock);
70 spin_unlock(&fifo->lock);
73 #define fifo_empty(fifo) ((fifo)->cnt == 0)
75 static inline int realloc_fifo(struct fifo_struct *fifo, size_t sz)
79 spin_lock(&fifo->lock);
80 if (!fifo_empty(fifo)) {
90 if ((fifo->buf = kmalloc(sz, GFP_KERNEL)) == NULL) {
100 spin_unlock(&fifo->lock);
104 static inline void write_word_to_fifo(struct fifo_struct *fifo,
107 spin_lock(&fifo->lock);
108 *(unsigned short *)&fifo->buf[fifo->wp] = word;
109 if ((fifo->wp += 2) == fifo->sz)
111 if ((fifo->cnt += 2) > fifo->sz)
112 fifo->cnt = fifo->sz;
113 spin_unlock(&fifo->lock);
119 * [*******----------*************]
121 * <----------------------------> sz = 30
122 * <-----> <-----------> cnt = 20
125 * <-> <-----------> count = 16
126 * <-----------> cnt1 = 13
130 * [---****-----------------------]
133 static inline ssize_t copy_to_user_fm_fifo(char *dst, struct fifo_struct *fifo,
139 /* fifo size can be zero */
143 spin_lock(&fifo->lock);
144 if (count > fifo->cnt)
147 if ((rp = fifo->wp - fifo->cnt) >= 0) {
148 /* valid area is straight */
149 if (copy_to_user(dst, &fifo->buf[rp], count)) {
157 /* requested area is straight */
158 if (copy_to_user(dst, &fifo->buf[rp], count)) {
163 if (copy_to_user(dst, &fifo->buf[rp], cnt1)) {
167 if (copy_to_user(dst+cnt1, fifo->buf, count-cnt1)) {
177 spin_unlock(&fifo->lock);