linux/include/linux/fsl/bestcomm/bestcomm.h
<<
>>
Prefs
   1/*
   2 * Public header for the MPC52xx processor BestComm driver
   3 *
   4 *
   5 * Copyright (C) 2006      Sylvain Munaut <tnt@246tNt.com>
   6 * Copyright (C) 2005      Varma Electronics Oy,
   7 *                         ( by Andrey Volkov <avolkov@varma-el.com> )
   8 * Copyright (C) 2003-2004 MontaVista, Software, Inc.
   9 *                         ( by Dale Farnsworth <dfarnsworth@mvista.com> )
  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
  19/**
  20 * struct bcom_bd - Structure describing a generic BestComm buffer descriptor
  21 * @status: The current status of this buffer. Exact meaning depends on the
  22 *          task type
  23 * @data: An array of u32 extra data.  Size of array is task dependent.
  24 *
  25 * Note: Don't dereference a bcom_bd pointer as an array.  The size of the
  26 *       bcom_bd is variable.  Use bcom_get_bd() instead.
  27 */
  28struct bcom_bd {
  29        u32     status;
  30        u32     data[]; /* variable payload size */
  31};
  32
  33/* ======================================================================== */
  34/* Generic task management                                                   */
  35/* ======================================================================== */
  36
  37/**
  38 * struct bcom_task - Structure describing a loaded BestComm task
  39 *
  40 * This structure is never built by the driver it self. It's built and
  41 * filled the intermediate layer of the BestComm API, the task dependent
  42 * support code.
  43 *
  44 * Most likely you don't need to poke around inside this structure. The
  45 * fields are exposed in the header just for the sake of inline functions
  46 */
  47struct bcom_task {
  48        unsigned int    tasknum;
  49        unsigned int    flags;
  50        int             irq;
  51
  52        struct bcom_bd  *bd;
  53        phys_addr_t     bd_pa;
  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
  66/**
  67 * bcom_enable - Enable a BestComm task
  68 * @tsk: The BestComm task structure
  69 *
  70 * This function makes sure the given task is enabled and can be run
  71 * by the BestComm engine as needed
  72 */
  73extern void bcom_enable(struct bcom_task *tsk);
  74
  75/**
  76 * bcom_disable - Disable a BestComm task
  77 * @tsk: The BestComm task structure
  78 *
  79 * This function disable a given task, making sure it's not executed
  80 * by the BestComm engine.
  81 */
  82extern void bcom_disable(struct bcom_task *tsk);
  83
  84
  85/**
  86 * bcom_get_task_irq - Returns the irq number of a BestComm task
  87 * @tsk: The BestComm task structure
  88 */
  89static inline int
  90bcom_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
 100/** _bcom_next_index - Get next input index.
 101 * @tsk: pointer to task structure
 102 *
 103 * Support function; Device drivers should not call this
 104 */
 105static 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
 111/** _bcom_next_outdex - Get next output index.
 112 * @tsk: pointer to task structure
 113 *
 114 * Support function; Device drivers should not call this
 115 */
 116static 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
 122/**
 123 * bcom_queue_empty - Checks if a BestComm task BD queue is empty
 124 * @tsk: The BestComm task structure
 125 */
 126static inline int
 127bcom_queue_empty(struct bcom_task *tsk)
 128{
 129        return tsk->index == tsk->outdex;
 130}
 131
 132/**
 133 * bcom_queue_full - Checks if a BestComm task BD queue is full
 134 * @tsk: The BestComm task structure
 135 */
 136static inline int
 137bcom_queue_full(struct bcom_task *tsk)
 138{
 139        return tsk->outdex == _bcom_next_index(tsk);
 140}
 141
 142/**
 143 * bcom_get_bd - Get a BD from the queue
 144 * @tsk: The BestComm task structure
 145 * index: Index of the BD to fetch
 146 */
 147static 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
 155/**
 156 * bcom_buffer_done - Checks if a BestComm 
 157 * @tsk: The BestComm task structure
 158 */
 159static inline int
 160bcom_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
 170/**
 171 * bcom_prepare_next_buffer - clear status of next available buffer.
 172 * @tsk: The BestComm task structure
 173 *
 174 * Returns pointer to next buffer descriptor
 175 */
 176static inline struct bcom_bd *
 177bcom_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
 186static inline void
 187bcom_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
 199static inline void *
 200bcom_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__ */
 214