Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202/* SPDX-License-Identifier: GPL-2.0 *//* * The contents of this file are private to DMA engine drivers, and is not * part of the API to be used by DMA engine users. */#ifndef DMAENGINE_H#define DMAENGINE_H
#include <linux/bug.h>#include <linux/dmaengine.h>
/** * dma_cookie_init - initialize the cookies for a DMA channel * @chan: dma channel to initialize */static inline void dma_cookie_init(struct dma_chan *chan){ chan->cookie = DMA_MIN_COOKIE; chan->completed_cookie = DMA_MIN_COOKIE;}
/** * dma_cookie_assign - assign a DMA engine cookie to the descriptor * @tx: descriptor needing cookie * * Assign a unique non-zero per-channel cookie to the descriptor. * Note: caller is expected to hold a lock to prevent concurrency. */static inline dma_cookie_t dma_cookie_assign(struct dma_async_tx_descriptor *tx){ struct dma_chan *chan = tx->chan; dma_cookie_t cookie;
cookie = chan->cookie + 1; if (cookie < DMA_MIN_COOKIE) cookie = DMA_MIN_COOKIE; tx->cookie = chan->cookie = cookie;
return cookie;}
/** * dma_cookie_complete - complete a descriptor * @tx: descriptor to complete * * Mark this descriptor complete by updating the channels completed * cookie marker. Zero the descriptors cookie to prevent accidental * repeated completions. * * Note: caller is expected to hold a lock to prevent concurrency. */static inline void dma_cookie_complete(struct dma_async_tx_descriptor *tx){ BUG_ON(tx->cookie < DMA_MIN_COOKIE); tx->chan->completed_cookie = tx->cookie; tx->cookie = 0;}
/** * dma_cookie_status - report cookie status * @chan: dma channel * @cookie: cookie we are interested in * @state: dma_tx_state structure to return last/used cookies * * Report the status of the cookie, filling in the state structure if * non-NULL. No locking is required. */static inline enum dma_status dma_cookie_status(struct dma_chan *chan, dma_cookie_t cookie, struct dma_tx_state *state){ dma_cookie_t used, complete;
used = chan->cookie; complete = chan->completed_cookie; barrier(); if (state) { state->last = complete; state->used = used; state->residue = 0; state->in_flight_bytes = 0; } return dma_async_is_complete(cookie, complete, used);}
static inline void dma_set_residue(struct dma_tx_state *state, u32 residue){ if (state) state->residue = residue;}
static inline void dma_set_in_flight_bytes(struct dma_tx_state *state, u32 in_flight_bytes){ if (state) state->in_flight_bytes = in_flight_bytes;}
struct dmaengine_desc_callback { dma_async_tx_callback callback; dma_async_tx_callback_result callback_result; void *callback_param;};
/** * dmaengine_desc_get_callback - get the passed in callback function * @tx: tx descriptor * @cb: temp struct to hold the callback info * * Fill the passed in cb struct with what's available in the passed in * tx descriptor struct * No locking is required. */static inline voiddmaengine_desc_get_callback(struct dma_async_tx_descriptor *tx, struct dmaengine_desc_callback *cb){ cb->callback = tx->callback; cb->callback_result = tx->callback_result; cb->callback_param = tx->callback_param;}
/** * dmaengine_desc_callback_invoke - call the callback function in cb struct * @cb: temp struct that is holding the callback info * @result: transaction result * * Call the callback function provided in the cb struct with the parameter * in the cb struct. * Locking is dependent on the driver. */static inline voiddmaengine_desc_callback_invoke(struct dmaengine_desc_callback *cb, const struct dmaengine_result *result){ struct dmaengine_result dummy_result = { .result = DMA_TRANS_NOERROR, .residue = 0 };
if (cb->callback_result) { if (!result) result = &dummy_result; cb->callback_result(cb->callback_param, result); } else if (cb->callback) { cb->callback(cb->callback_param); }}
/** * dmaengine_desc_get_callback_invoke - get the callback in tx descriptor and * then immediately call the callback. * @tx: dma async tx descriptor * @result: transaction result * * Call dmaengine_desc_get_callback() and dmaengine_desc_callback_invoke() * in a single function since no work is necessary in between for the driver. * Locking is dependent on the driver. */static inline voiddmaengine_desc_get_callback_invoke(struct dma_async_tx_descriptor *tx, const struct dmaengine_result *result){ struct dmaengine_desc_callback cb;
dmaengine_desc_get_callback(tx, &cb); dmaengine_desc_callback_invoke(&cb, result);}
/** * dmaengine_desc_callback_valid - verify the callback is valid in cb * @cb: callback info struct * * Return a bool that verifies whether callback in cb is valid or not. * No locking is required. */static inline booldmaengine_desc_callback_valid(struct dmaengine_desc_callback *cb){ return cb->callback || cb->callback_result;}
struct dma_chan *dma_get_slave_channel(struct dma_chan *chan);struct dma_chan *dma_get_any_slave_channel(struct dma_device *device);
#ifdef CONFIG_DEBUG_FS#include <linux/debugfs.h>
static inline struct dentry *dmaengine_get_debugfs_root(struct dma_device *dma_dev) { return dma_dev->dbg_dev_root;}#elsestruct dentry;static inline struct dentry *dmaengine_get_debugfs_root(struct dma_device *dma_dev){ return NULL;}#endif /* CONFIG_DEBUG_FS */
#endif