Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
bestcomm.h
Go to the documentation of this file.
1 /*
2  * Public header for the MPC52xx processor BestComm driver
3  *
4  *
5  * Copyright (C) 2006 Sylvain Munaut <[email protected]>
6  * Copyright (C) 2005 Varma Electronics Oy,
7  * ( by Andrey Volkov <[email protected]> )
8  * Copyright (C) 2003-2004 MontaVista, Software, Inc.
9  * ( by Dale Farnsworth <[email protected]> )
10  *
11  * This file is licensed under the terms of the GNU General Public License
12  * version 2. This program is licensed "as is" without any warranty of any
13  * kind, whether express or implied.
14  */
15 
16 #ifndef __BESTCOMM_H__
17 #define __BESTCOMM_H__
18 
28 struct bcom_bd {
30  u32 data[0]; /* variable payload size */
31 };
32 
33 /* ======================================================================== */
34 /* Generic task management */
35 /* ======================================================================== */
36 
47 struct bcom_task {
48  unsigned int tasknum;
49  unsigned int flags;
50  int irq;
51 
52  struct bcom_bd *bd;
54  void **cookie;
55  unsigned short index;
56  unsigned short outdex;
57  unsigned int num_bd;
58  unsigned int bd_size;
59 
60  void* priv;
61 };
62 
63 #define BCOM_FLAGS_NONE 0x00000000ul
64 #define BCOM_FLAGS_ENABLE_TASK (1ul << 0)
65 
73 extern void bcom_enable(struct bcom_task *tsk);
74 
82 extern void bcom_disable(struct bcom_task *tsk);
83 
84 
89 static inline int
90 bcom_get_task_irq(struct bcom_task *tsk) {
91  return tsk->irq;
92 }
93 
94 /* ======================================================================== */
95 /* BD based tasks helpers */
96 /* ======================================================================== */
97 
98 #define BCOM_BD_READY 0x40000000ul
99 
105 static inline int
106 _bcom_next_index(struct bcom_task *tsk)
107 {
108  return ((tsk->index + 1) == tsk->num_bd) ? 0 : tsk->index + 1;
109 }
110 
116 static inline int
117 _bcom_next_outdex(struct bcom_task *tsk)
118 {
119  return ((tsk->outdex + 1) == tsk->num_bd) ? 0 : tsk->outdex + 1;
120 }
121 
126 static inline int
127 bcom_queue_empty(struct bcom_task *tsk)
128 {
129  return tsk->index == tsk->outdex;
130 }
131 
136 static inline int
137 bcom_queue_full(struct bcom_task *tsk)
138 {
139  return tsk->outdex == _bcom_next_index(tsk);
140 }
141 
147 static inline struct bcom_bd
148 *bcom_get_bd(struct bcom_task *tsk, unsigned int index)
149 {
150  /* A cast to (void*) so the address can be incremented by the
151  * real size instead of by sizeof(struct bcom_bd) */
152  return ((void *)tsk->bd) + (index * tsk->bd_size);
153 }
154 
159 static inline int
160 bcom_buffer_done(struct bcom_task *tsk)
161 {
162  struct bcom_bd *bd;
163  if (bcom_queue_empty(tsk))
164  return 0;
165 
166  bd = bcom_get_bd(tsk, tsk->outdex);
167  return !(bd->status & BCOM_BD_READY);
168 }
169 
176 static inline struct bcom_bd *
177 bcom_prepare_next_buffer(struct bcom_task *tsk)
178 {
179  struct bcom_bd *bd;
180 
181  bd = bcom_get_bd(tsk, tsk->index);
182  bd->status = 0; /* cleanup last status */
183  return bd;
184 }
185 
186 static inline void
187 bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie)
188 {
189  struct bcom_bd *bd = bcom_get_bd(tsk, tsk->index);
190 
191  tsk->cookie[tsk->index] = cookie;
192  mb(); /* ensure the bd is really up-to-date */
193  bd->status |= BCOM_BD_READY;
194  tsk->index = _bcom_next_index(tsk);
195  if (tsk->flags & BCOM_FLAGS_ENABLE_TASK)
196  bcom_enable(tsk);
197 }
198 
199 static inline void *
200 bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd)
201 {
202  void *cookie = tsk->cookie[tsk->outdex];
203  struct bcom_bd *bd = bcom_get_bd(tsk, tsk->outdex);
204 
205  if (p_status)
206  *p_status = bd->status;
207  if (p_bd)
208  *p_bd = bd;
209  tsk->outdex = _bcom_next_outdex(tsk);
210  return cookie;
211 }
212 
213 #endif /* __BESTCOMM_H__ */