]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/plat-omap/mailbox.h
c3f8f2c56b4f15c17412014be824ee6f27724221
[linux-2.6-omap-h63xx.git] / arch / arm / plat-omap / mailbox.h
1 /*
2  * Mailbox internal functions
3  *
4  * Copyright (C) 2006 Nokia Corporation
5  * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
6  *
7  * This file is subject to the terms and conditions of the GNU General Public
8  * License.  See the file "COPYING" in the main directory of this archive
9  * for more details.
10  */
11
12 #ifndef __ARCH_ARM_PLAT_MAILBOX_H
13 #define __ARCH_ARM_PLAT_MAILBOX_H
14
15 /*
16  * Mailbox queue handling API
17  */
18
19 #define MBQ_DEPTH       16
20 struct omap_mbq {
21         rwlock_t lock;
22         mbox_msg_t msg[MBQ_DEPTH];
23         mbox_msg_t *rp, *wp;
24         int cnt;
25 };
26
27 static inline int mbq_init(struct omap_mbq **addr)
28 {
29         struct omap_mbq *m = kmalloc(sizeof(struct omap_mbq), GFP_KERNEL);
30         if (!m)
31                 return -ENOMEM;
32
33         rwlock_init(&m->lock);
34
35         write_lock_irq(&m->lock);
36         m->rp = m->wp = &m->msg[0];
37         m->cnt = 0;
38         write_unlock_irq(&m->lock);
39
40         *addr = m;
41
42         return 0;
43 }
44
45 static inline int mbq_empty(struct omap_mbq *mbq)
46 {
47         int ret;
48
49         read_lock_irq(&mbq->lock);
50         ret = (mbq->cnt == 0);
51         read_unlock_irq(&mbq->lock);
52
53         return ret;
54 }
55
56 static inline int mbq_full(struct omap_mbq *mbq)
57 {
58         int ret;
59
60         read_lock_irq(&mbq->lock);
61         ret = (mbq->cnt == MBQ_DEPTH);
62         read_unlock_irq(&mbq->lock);
63
64         return ret;
65 }
66
67 static inline int mbq_add(struct omap_mbq *mbq, mbox_msg_t msg)
68 {
69         int ret = 0;
70
71         write_lock_irq(&mbq->lock);
72
73         *mbq->wp = msg;
74         if (++mbq->wp == &mbq->msg[MBQ_DEPTH])
75                 mbq->wp = &mbq->msg[0];
76
77         if (++mbq->cnt == MBQ_DEPTH)    /* full */
78                 ret = -1;
79
80         write_unlock_irq(&mbq->lock);
81
82         return ret;
83 }
84
85 static inline mbox_msg_t mbq_get(struct omap_mbq *mbq)
86 {
87         mbox_msg_t msg;
88
89         write_lock_irq(&mbq->lock);
90
91         msg = *mbq->rp;
92
93         if (++mbq->rp == &mbq->msg[MBQ_DEPTH])
94                 mbq->rp = &mbq->msg[0];
95         mbq->cnt--;
96
97         write_unlock_irq(&mbq->lock);
98
99         return msg;
100 }
101
102 static inline void mbq_exit(struct omap_mbq **addr)
103 {
104         if (*addr)
105                 kfree(*addr);
106 }
107
108 /*
109  * Mailbox sequence bit API
110  */
111 #if defined(CONFIG_ARCH_OMAP1)
112 #  define MBOX_USE_SEQ_BIT
113 #elif defined(CONFIG_ARCH_OMAP2)
114 #  define MBOX_USE_SEQ_BIT
115 #endif
116
117 #ifdef MBOX_USE_SEQ_BIT
118 /* seq_rcv should be initialized with any value other than
119  * 0 and 1 << 31, to allow either value for the first
120  * message.  */
121 static inline void mbox_seq_init(struct omap_mbox *mbox)
122 {
123         /* any value other than 0 and 1 << 31 */
124         mbox->seq_rcv = 0xffffffff;
125 }
126
127 static inline void mbox_seq_toggle(struct omap_mbox *mbox, mbox_msg_t * msg)
128 {
129         /* add seq_snd to msg */
130         *msg = (*msg & 0x7fffffff) | mbox->seq_snd;
131         /* flip seq_snd */
132         mbox->seq_snd ^= 1 << 31;
133 }
134
135 static inline int mbox_seq_test(struct omap_mbox *mbox, mbox_msg_t msg)
136 {
137         mbox_msg_t seq = msg & (1 << 31);
138         if (seq == mbox->seq_rcv)
139                 return -1;
140         mbox->seq_rcv = seq;
141         return 0;
142 }
143 #else
144 static inline void mbox_seq_init(struct omap_mbox *mbox)
145 {
146 }
147 static inline void mbox_seq_toggle(struct omap_mbox *mbox, mbox_msg_t * msg)
148 {
149 }
150 static inline int mbox_seq_test(struct omap_mbox *mbox, mbox_msg_t msg)
151 {
152         return 0;
153 }
154 #endif
155
156 /* Mailbox FIFO handle functions */
157 static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
158 {
159         return mbox->ops->fifo_read(mbox);
160 }
161 static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
162 {
163         mbox->ops->fifo_write(mbox, msg);
164 }
165 static inline int mbox_fifo_empty(struct omap_mbox *mbox)
166 {
167         return mbox->ops->fifo_empty(mbox);
168 }
169 static inline int mbox_fifo_full(struct omap_mbox *mbox)
170 {
171         return mbox->ops->fifo_full(mbox);
172 }
173
174 /* Mailbox IRQ handle functions */
175 static inline void enable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
176 {
177         mbox->ops->enable_irq(mbox, irq);
178 }
179 static inline void disable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
180 {
181         mbox->ops->disable_irq(mbox, irq);
182 }
183 static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
184 {
185         if (mbox->ops->ack_irq)
186                 mbox->ops->ack_irq(mbox, irq);
187 }
188 static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
189 {
190         return mbox->ops->is_irq(mbox, irq);
191 }
192
193 #endif                          /* __ARCH_ARM_PLAT_MAILBOX_H */