Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * The contents of this file are private to DMA engine drivers, and is not
0004  * part of the API to be used by DMA engine users.
0005  */
0006 #ifndef DMAENGINE_H
0007 #define DMAENGINE_H
0008 
0009 #include <linux/bug.h>
0010 #include <linux/dmaengine.h>
0011 
0012 /**
0013  * dma_cookie_init - initialize the cookies for a DMA channel
0014  * @chan: dma channel to initialize
0015  */
0016 static inline void dma_cookie_init(struct dma_chan *chan)
0017 {
0018     chan->cookie = DMA_MIN_COOKIE;
0019     chan->completed_cookie = DMA_MIN_COOKIE;
0020 }
0021 
0022 /**
0023  * dma_cookie_assign - assign a DMA engine cookie to the descriptor
0024  * @tx: descriptor needing cookie
0025  *
0026  * Assign a unique non-zero per-channel cookie to the descriptor.
0027  * Note: caller is expected to hold a lock to prevent concurrency.
0028  */
0029 static inline dma_cookie_t dma_cookie_assign(struct dma_async_tx_descriptor *tx)
0030 {
0031     struct dma_chan *chan = tx->chan;
0032     dma_cookie_t cookie;
0033 
0034     cookie = chan->cookie + 1;
0035     if (cookie < DMA_MIN_COOKIE)
0036         cookie = DMA_MIN_COOKIE;
0037     tx->cookie = chan->cookie = cookie;
0038 
0039     return cookie;
0040 }
0041 
0042 /**
0043  * dma_cookie_complete - complete a descriptor
0044  * @tx: descriptor to complete
0045  *
0046  * Mark this descriptor complete by updating the channels completed
0047  * cookie marker.  Zero the descriptors cookie to prevent accidental
0048  * repeated completions.
0049  *
0050  * Note: caller is expected to hold a lock to prevent concurrency.
0051  */
0052 static inline void dma_cookie_complete(struct dma_async_tx_descriptor *tx)
0053 {
0054     BUG_ON(tx->cookie < DMA_MIN_COOKIE);
0055     tx->chan->completed_cookie = tx->cookie;
0056     tx->cookie = 0;
0057 }
0058 
0059 /**
0060  * dma_cookie_status - report cookie status
0061  * @chan: dma channel
0062  * @cookie: cookie we are interested in
0063  * @state: dma_tx_state structure to return last/used cookies
0064  *
0065  * Report the status of the cookie, filling in the state structure if
0066  * non-NULL.  No locking is required.
0067  */
0068 static inline enum dma_status dma_cookie_status(struct dma_chan *chan,
0069     dma_cookie_t cookie, struct dma_tx_state *state)
0070 {
0071     dma_cookie_t used, complete;
0072 
0073     used = chan->cookie;
0074     complete = chan->completed_cookie;
0075     barrier();
0076     if (state) {
0077         state->last = complete;
0078         state->used = used;
0079         state->residue = 0;
0080         state->in_flight_bytes = 0;
0081     }
0082     return dma_async_is_complete(cookie, complete, used);
0083 }
0084 
0085 static inline void dma_set_residue(struct dma_tx_state *state, u32 residue)
0086 {
0087     if (state)
0088         state->residue = residue;
0089 }
0090 
0091 static inline void dma_set_in_flight_bytes(struct dma_tx_state *state,
0092                        u32 in_flight_bytes)
0093 {
0094     if (state)
0095         state->in_flight_bytes = in_flight_bytes;
0096 }
0097 
0098 struct dmaengine_desc_callback {
0099     dma_async_tx_callback callback;
0100     dma_async_tx_callback_result callback_result;
0101     void *callback_param;
0102 };
0103 
0104 /**
0105  * dmaengine_desc_get_callback - get the passed in callback function
0106  * @tx: tx descriptor
0107  * @cb: temp struct to hold the callback info
0108  *
0109  * Fill the passed in cb struct with what's available in the passed in
0110  * tx descriptor struct
0111  * No locking is required.
0112  */
0113 static inline void
0114 dmaengine_desc_get_callback(struct dma_async_tx_descriptor *tx,
0115                 struct dmaengine_desc_callback *cb)
0116 {
0117     cb->callback = tx->callback;
0118     cb->callback_result = tx->callback_result;
0119     cb->callback_param = tx->callback_param;
0120 }
0121 
0122 /**
0123  * dmaengine_desc_callback_invoke - call the callback function in cb struct
0124  * @cb: temp struct that is holding the callback info
0125  * @result: transaction result
0126  *
0127  * Call the callback function provided in the cb struct with the parameter
0128  * in the cb struct.
0129  * Locking is dependent on the driver.
0130  */
0131 static inline void
0132 dmaengine_desc_callback_invoke(struct dmaengine_desc_callback *cb,
0133                    const struct dmaengine_result *result)
0134 {
0135     struct dmaengine_result dummy_result = {
0136         .result = DMA_TRANS_NOERROR,
0137         .residue = 0
0138     };
0139 
0140     if (cb->callback_result) {
0141         if (!result)
0142             result = &dummy_result;
0143         cb->callback_result(cb->callback_param, result);
0144     } else if (cb->callback) {
0145         cb->callback(cb->callback_param);
0146     }
0147 }
0148 
0149 /**
0150  * dmaengine_desc_get_callback_invoke - get the callback in tx descriptor and
0151  *                  then immediately call the callback.
0152  * @tx: dma async tx descriptor
0153  * @result: transaction result
0154  *
0155  * Call dmaengine_desc_get_callback() and dmaengine_desc_callback_invoke()
0156  * in a single function since no work is necessary in between for the driver.
0157  * Locking is dependent on the driver.
0158  */
0159 static inline void
0160 dmaengine_desc_get_callback_invoke(struct dma_async_tx_descriptor *tx,
0161                    const struct dmaengine_result *result)
0162 {
0163     struct dmaengine_desc_callback cb;
0164 
0165     dmaengine_desc_get_callback(tx, &cb);
0166     dmaengine_desc_callback_invoke(&cb, result);
0167 }
0168 
0169 /**
0170  * dmaengine_desc_callback_valid - verify the callback is valid in cb
0171  * @cb: callback info struct
0172  *
0173  * Return a bool that verifies whether callback in cb is valid or not.
0174  * No locking is required.
0175  */
0176 static inline bool
0177 dmaengine_desc_callback_valid(struct dmaengine_desc_callback *cb)
0178 {
0179     return cb->callback || cb->callback_result;
0180 }
0181 
0182 struct dma_chan *dma_get_slave_channel(struct dma_chan *chan);
0183 struct dma_chan *dma_get_any_slave_channel(struct dma_device *device);
0184 
0185 #ifdef CONFIG_DEBUG_FS
0186 #include <linux/debugfs.h>
0187 
0188 static inline struct dentry *
0189 dmaengine_get_debugfs_root(struct dma_device *dma_dev) {
0190     return dma_dev->dbg_dev_root;
0191 }
0192 #else
0193 struct dentry;
0194 static inline struct dentry *
0195 dmaengine_get_debugfs_root(struct dma_device *dma_dev)
0196 {
0197     return NULL;
0198 }
0199 #endif /* CONFIG_DEBUG_FS */
0200 
0201 #endif