aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2016-07-20 16:13:50 -0400
committerVinod Koul <vinod.koul@intel.com>2016-08-07 22:41:42 -0400
commitf067025bc676ba8d18fba5f959598339e39b86db (patch)
treeda3f27f613b3c299cbd16434c57fdb90ddf1c970
parentb1f884a5ff23534c3808926aeb62187be55e751e (diff)
dmaengine: add support to provide error result from a DMA transation
Adding a new callback that will provide the error result for a transaction. The result is allocated on the stack and the callback should create a copy if it wishes to retain the information after exiting. The result parameter is now defined and takes over the dummy void pointer we placed in the helper functions previously. dmaengine drivers should start converting to the new "callback_result" callback in order to receive transaction results. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r--drivers/dma/dmaengine.h22
-rw-r--r--include/linux/dmaengine.h16
2 files changed, 33 insertions, 5 deletions
diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
index 94a4379c7639..882ff9448c3b 100644
--- a/drivers/dma/dmaengine.h
+++ b/drivers/dma/dmaengine.h
@@ -88,6 +88,7 @@ static inline void dma_set_residue(struct dma_tx_state *state, u32 residue)
88 88
89struct dmaengine_desc_callback { 89struct dmaengine_desc_callback {
90 dma_async_tx_callback callback; 90 dma_async_tx_callback callback;
91 dma_async_tx_callback_result callback_result;
91 void *callback_param; 92 void *callback_param;
92}; 93};
93 94
@@ -105,13 +106,14 @@ dmaengine_desc_get_callback(struct dma_async_tx_descriptor *tx,
105 struct dmaengine_desc_callback *cb) 106 struct dmaengine_desc_callback *cb)
106{ 107{
107 cb->callback = tx->callback; 108 cb->callback = tx->callback;
109 cb->callback_result = tx->callback_result;
108 cb->callback_param = tx->callback_param; 110 cb->callback_param = tx->callback_param;
109} 111}
110 112
111/** 113/**
112 * dmaengine_desc_callback_invoke - call the callback function in cb struct 114 * dmaengine_desc_callback_invoke - call the callback function in cb struct
113 * @cb: temp struct that is holding the callback info 115 * @cb: temp struct that is holding the callback info
114 * @result: dummy pointer for now 116 * @result: transaction result
115 * 117 *
116 * Call the callback function provided in the cb struct with the parameter 118 * Call the callback function provided in the cb struct with the parameter
117 * in the cb struct. 119 * in the cb struct.
@@ -119,17 +121,27 @@ dmaengine_desc_get_callback(struct dma_async_tx_descriptor *tx,
119 */ 121 */
120static inline void 122static inline void
121dmaengine_desc_callback_invoke(struct dmaengine_desc_callback *cb, 123dmaengine_desc_callback_invoke(struct dmaengine_desc_callback *cb,
122 const void *result) 124 const struct dmaengine_result *result)
123{ 125{
124 if (cb->callback) 126 struct dmaengine_result dummy_result = {
127 .result = DMA_TRANS_NOERROR,
128 .residue = 0
129 };
130
131 if (cb->callback_result) {
132 if (!result)
133 result = &dummy_result;
134 cb->callback_result(cb->callback_param, result);
135 } else if (cb->callback) {
125 cb->callback(cb->callback_param); 136 cb->callback(cb->callback_param);
137 }
126} 138}
127 139
128/** 140/**
129 * dmaengine_desc_get_callback_invoke - get the callback in tx descriptor and 141 * dmaengine_desc_get_callback_invoke - get the callback in tx descriptor and
130 * then immediately call the callback. 142 * then immediately call the callback.
131 * @tx: dma async tx descriptor 143 * @tx: dma async tx descriptor
132 * @result: dummy pointer for now 144 * @result: transaction result
133 * 145 *
134 * Call dmaengine_desc_get_callback() and dmaengine_desc_callback_invoke() 146 * Call dmaengine_desc_get_callback() and dmaengine_desc_callback_invoke()
135 * in a single function since no work is necessary in between for the driver. 147 * in a single function since no work is necessary in between for the driver.
@@ -137,7 +149,7 @@ dmaengine_desc_callback_invoke(struct dmaengine_desc_callback *cb,
137 */ 149 */
138static inline void 150static inline void
139dmaengine_desc_get_callback_invoke(struct dma_async_tx_descriptor *tx, 151dmaengine_desc_get_callback_invoke(struct dma_async_tx_descriptor *tx,
140 const void *result) 152 const struct dmaengine_result *result)
141{ 153{
142 struct dmaengine_desc_callback cb; 154 struct dmaengine_desc_callback cb;
143 155
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 30de0197263a..cc535a478bae 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -441,6 +441,21 @@ typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);
441 441
442typedef void (*dma_async_tx_callback)(void *dma_async_param); 442typedef void (*dma_async_tx_callback)(void *dma_async_param);
443 443
444enum dmaengine_tx_result {
445 DMA_TRANS_NOERROR = 0, /* SUCCESS */
446 DMA_TRANS_READ_FAILED, /* Source DMA read failed */
447 DMA_TRANS_WRITE_FAILED, /* Destination DMA write failed */
448 DMA_TRANS_ABORTED, /* Op never submitted / aborted */
449};
450
451struct dmaengine_result {
452 enum dmaengine_tx_result result;
453 u32 residue;
454};
455
456typedef void (*dma_async_tx_callback_result)(void *dma_async_param,
457 const struct dmaengine_result *result);
458
444struct dmaengine_unmap_data { 459struct dmaengine_unmap_data {
445 u8 map_cnt; 460 u8 map_cnt;
446 u8 to_cnt; 461 u8 to_cnt;
@@ -478,6 +493,7 @@ struct dma_async_tx_descriptor {
478 dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx); 493 dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx);
479 int (*desc_free)(struct dma_async_tx_descriptor *tx); 494 int (*desc_free)(struct dma_async_tx_descriptor *tx);
480 dma_async_tx_callback callback; 495 dma_async_tx_callback callback;
496 dma_async_tx_callback_result callback_result;
481 void *callback_param; 497 void *callback_param;
482 struct dmaengine_unmap_data *unmap; 498 struct dmaengine_unmap_data *unmap;
483#ifdef CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH 499#ifdef CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH