linux/drivers/dma/dmaengine.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * The contents of this file are private to DMA engine drivers, and is not
   4 * part of the API to be used by DMA engine users.
   5 */
   6#ifndef DMAENGINE_H
   7#define DMAENGINE_H
   8
   9#include <linux/bug.h>
  10#include <linux/dmaengine.h>
  11
  12/**
  13 * dma_cookie_init - initialize the cookies for a DMA channel
  14 * @chan: dma channel to initialize
  15 */
  16static inline void dma_cookie_init(struct dma_chan *chan)
  17{
  18        chan->cookie = DMA_MIN_COOKIE;
  19        chan->completed_cookie = DMA_MIN_COOKIE;
  20}
  21
  22/**
  23 * dma_cookie_assign - assign a DMA engine cookie to the descriptor
  24 * @tx: descriptor needing cookie
  25 *
  26 * Assign a unique non-zero per-channel cookie to the descriptor.
  27 * Note: caller is expected to hold a lock to prevent concurrency.
  28 */
  29static inline dma_cookie_t dma_cookie_assign(struct dma_async_tx_descriptor *tx)
  30{
  31        struct dma_chan *chan = tx->chan;
  32        dma_cookie_t cookie;
  33
  34        cookie = chan->cookie + 1;
  35        if (cookie < DMA_MIN_COOKIE)
  36                cookie = DMA_MIN_COOKIE;
  37        tx->cookie = chan->cookie = cookie;
  38
  39        return cookie;
  40}
  41
  42/**
  43 * dma_cookie_complete - complete a descriptor
  44 * @tx: descriptor to complete
  45 *
  46 * Mark this descriptor complete by updating the channels completed
  47 * cookie marker.  Zero the descriptors cookie to prevent accidental
  48 * repeated completions.
  49 *
  50 * Note: caller is expected to hold a lock to prevent concurrency.
  51 */
  52static inline void dma_cookie_complete(struct dma_async_tx_descriptor *tx)
  53{
  54        BUG_ON(tx->cookie < DMA_MIN_COOKIE);
  55        tx->chan->completed_cookie = tx->cookie;
  56        tx->cookie = 0;
  57}
  58
  59/**
  60 * dma_cookie_status - report cookie status
  61 * @chan: dma channel
  62 * @cookie: cookie we are interested in
  63 * @state: dma_tx_state structure to return last/used cookies
  64 *
  65 * Report the status of the cookie, filling in the state structure if
  66 * non-NULL.  No locking is required.
  67 */
  68static inline enum dma_status dma_cookie_status(struct dma_chan *chan,
  69        dma_cookie_t cookie, struct dma_tx_state *state)
  70{
  71        dma_cookie_t used, complete;
  72
  73        used = chan->cookie;
  74        complete = chan->completed_cookie;
  75        barrier();
  76        if (state) {
  77                state->last = complete;
  78                state->used = used;
  79                state->residue = 0;
  80                state->in_flight_bytes = 0;
  81        }
  82        return dma_async_is_complete(cookie, complete, used);
  83}
  84
  85static inline void dma_set_residue(struct dma_tx_state *state, u32 residue)
  86{
  87        if (state)
  88                state->residue = residue;
  89}
  90
  91static inline void dma_set_in_flight_bytes(struct dma_tx_state *state,
  92                                           u32 in_flight_bytes)
  93{
  94        if (state)
  95                state->in_flight_bytes = in_flight_bytes;
  96}
  97
  98struct dmaengine_desc_callback {
  99        dma_async_tx_callback callback;
 100        dma_async_tx_callback_result callback_result;
 101        void *callback_param;
 102};
 103
 104/**
 105 * dmaengine_desc_get_callback - get the passed in callback function
 106 * @tx: tx descriptor
 107 * @cb: temp struct to hold the callback info
 108 *
 109 * Fill the passed in cb struct with what's available in the passed in
 110 * tx descriptor struct
 111 * No locking is required.
 112 */
 113static inline void
 114dmaengine_desc_get_callback(struct dma_async_tx_descriptor *tx,
 115                            struct dmaengine_desc_callback *cb)
 116{
 117        cb->callback = tx->callback;
 118        cb->callback_result = tx->callback_result;
 119        cb->callback_param = tx->callback_param;
 120}
 121
 122/**
 123 * dmaengine_desc_callback_invoke - call the callback function in cb struct
 124 * @cb: temp struct that is holding the callback info
 125 * @result: transaction result
 126 *
 127 * Call the callback function provided in the cb struct with the parameter
 128 * in the cb struct.
 129 * Locking is dependent on the driver.
 130 */
 131static inline void
 132dmaengine_desc_callback_invoke(struct dmaengine_desc_callback *cb,
 133                               const struct dmaengine_result *result)
 134{
 135        struct dmaengine_result dummy_result = {
 136                .result = DMA_TRANS_NOERROR,
 137                .residue = 0
 138        };
 139
 140        if (cb->callback_result) {
 141                if (!result)
 142                        result = &dummy_result;
 143                cb->callback_result(cb->callback_param, result);
 144        } else if (cb->callback) {
 145                cb->callback(cb->callback_param);
 146        }
 147}
 148
 149/**
 150 * dmaengine_desc_get_callback_invoke - get the callback in tx descriptor and
 151 *                                      then immediately call the callback.
 152 * @tx: dma async tx descriptor
 153 * @result: transaction result
 154 *
 155 * Call dmaengine_desc_get_callback() and dmaengine_desc_callback_invoke()
 156 * in a single function since no work is necessary in between for the driver.
 157 * Locking is dependent on the driver.
 158 */
 159static inline void
 160dmaengine_desc_get_callback_invoke(struct dma_async_tx_descriptor *tx,
 161                                   const struct dmaengine_result *result)
 162{
 163        struct dmaengine_desc_callback cb;
 164
 165        dmaengine_desc_get_callback(tx, &cb);
 166        dmaengine_desc_callback_invoke(&cb, result);
 167}
 168
 169/**
 170 * dmaengine_desc_callback_valid - verify the callback is valid in cb
 171 * @cb: callback info struct
 172 *
 173 * Return a bool that verifies whether callback in cb is valid or not.
 174 * No locking is required.
 175 */
 176static inline bool
 177dmaengine_desc_callback_valid(struct dmaengine_desc_callback *cb)
 178{
 179        return (cb->callback) ? true : false;
 180}
 181
 182struct dma_chan *dma_get_slave_channel(struct dma_chan *chan);
 183struct dma_chan *dma_get_any_slave_channel(struct dma_device *device);
 184
 185#ifdef CONFIG_DEBUG_FS
 186#include <linux/debugfs.h>
 187
 188static inline struct dentry *
 189dmaengine_get_debugfs_root(struct dma_device *dma_dev) {
 190        return dma_dev->dbg_dev_root;
 191}
 192#else
 193struct dentry;
 194static inline struct dentry *
 195dmaengine_get_debugfs_root(struct dma_device *dma_dev)
 196{
 197        return NULL;
 198}
 199#endif /* CONFIG_DEBUG_FS */
 200
 201#endif
 202