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