aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/dmaengine.h
diff options
context:
space:
mode:
authorHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-07-08 14:59:35 -0400
committerDan Williams <dan.j.williams@intel.com>2008-07-08 14:59:35 -0400
commitdc0ee6435cb92ccc81b14ff28d163fecc5a7f120 (patch)
tree0a494946593f36516a997f64cb299d898cdf463f /include/linux/dmaengine.h
parente1d181efb14a93cf263d6c588a5395518edf3294 (diff)
dmaengine: Add slave DMA interface
This patch adds the necessary interfaces to the DMA Engine framework to use functionality found on most embedded DMA controllers: DMA from and to I/O registers with hardware handshaking. In this context, hardware hanshaking means that the peripheral that owns the I/O registers in question is able to tell the DMA controller when more data is available for reading, or when there is room for more data to be written. This usually happens internally on the chip, but these signals may also be exported outside the chip for things like IDE DMA, etc. A new struct dma_slave is introduced. This contains information that the DMA engine driver needs to set up slave transfers to and from a slave device. Most engines supporting DMA slave transfers will want to extend this structure with controller-specific parameters. This additional information is usually passed from the platform/board code through the client driver. A "slave" pointer is added to the dma_client struct. This must point to a valid dma_slave structure iff the DMA_SLAVE capability is requested. The DMA engine driver may use this information in its device_alloc_chan_resources hook to configure the DMA controller for slave transfers from and to the given slave device. A new operation for preparing slave DMA transfers is added to struct dma_device. This takes a scatterlist and returns a single descriptor representing the whole transfer. Another new operation for terminating all pending transfers is added as well. The latter is needed because there may be errors outside the scope of the DMA Engine framework that may require DMA operations to be terminated prematurely. DMA Engine drivers may extend the dma_device, dma_chan and/or dma_slave_descriptor structures to allow controller-specific operations. The client driver can detect such extensions by looking at the DMA Engine's struct device, or it can request a specific DMA Engine device by setting the dma_dev field in struct dma_slave. dmaslave interface changes since v4: * Fix checkpatch errors * Fix changelog (there are no slave descriptors anymore) dmaslave interface changes since v3: * Use dma_data_direction instead of a new enum * Submit slave transfers as scatterlists * Remove the DMA slave descriptor struct dmaslave interface changes since v2: * Add a dma_dev field to struct dma_slave. If set, the client can only be bound to the DMA controller that corresponds to this device. This allows controller-specific extensions of the dma_slave structure; if the device matches, the controller may safely assume its extensions are present. * Move reg_width into struct dma_slave as there are currently no users that need to be able to set the width on a per-transfer basis. dmaslave interface changes since v1: * Drop the set_direction and set_width descriptor hooks. Pass the direction and width to the prep function instead. * Declare a dma_slave struct with fixed information about a slave, i.e. register addresses, handshake interfaces and such. * Add pointer to a dma_slave struct to dma_client. Can be NULL if the DMA_SLAVE capability isn't requested. * Drop the set_slave device hook since the alloc_chan_resources hook now has enough information to set up the channel for slave transfers. Acked-by: Maciej Sosnowski <maciej.sosnowski@intel.com> Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'include/linux/dmaengine.h')
-rw-r--r--include/linux/dmaengine.h52
1 files changed, 51 insertions, 1 deletions
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index b058d6360383..9b91d341e1fa 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -89,10 +89,23 @@ enum dma_transaction_type {
89 DMA_MEMSET, 89 DMA_MEMSET,
90 DMA_MEMCPY_CRC32C, 90 DMA_MEMCPY_CRC32C,
91 DMA_INTERRUPT, 91 DMA_INTERRUPT,
92 DMA_SLAVE,
92}; 93};
93 94
94/* last transaction type for creation of the capabilities mask */ 95/* last transaction type for creation of the capabilities mask */
95#define DMA_TX_TYPE_END (DMA_INTERRUPT + 1) 96#define DMA_TX_TYPE_END (DMA_SLAVE + 1)
97
98/**
99 * enum dma_slave_width - DMA slave register access width.
100 * @DMA_SLAVE_WIDTH_8BIT: Do 8-bit slave register accesses
101 * @DMA_SLAVE_WIDTH_16BIT: Do 16-bit slave register accesses
102 * @DMA_SLAVE_WIDTH_32BIT: Do 32-bit slave register accesses
103 */
104enum dma_slave_width {
105 DMA_SLAVE_WIDTH_8BIT,
106 DMA_SLAVE_WIDTH_16BIT,
107 DMA_SLAVE_WIDTH_32BIT,
108};
96 109
97/** 110/**
98 * enum dma_ctrl_flags - DMA flags to augment operation preparation, 111 * enum dma_ctrl_flags - DMA flags to augment operation preparation,
@@ -119,6 +132,32 @@ enum dma_ctrl_flags {
119typedef struct { DECLARE_BITMAP(bits, DMA_TX_TYPE_END); } dma_cap_mask_t; 132typedef struct { DECLARE_BITMAP(bits, DMA_TX_TYPE_END); } dma_cap_mask_t;
120 133
121/** 134/**
135 * struct dma_slave - Information about a DMA slave
136 * @dev: device acting as DMA slave
137 * @dma_dev: required DMA master device. If non-NULL, the client can not be
138 * bound to other masters than this.
139 * @tx_reg: physical address of data register used for
140 * memory-to-peripheral transfers
141 * @rx_reg: physical address of data register used for
142 * peripheral-to-memory transfers
143 * @reg_width: peripheral register width
144 *
145 * If dma_dev is non-NULL, the client can not be bound to other DMA
146 * masters than the one corresponding to this device. The DMA master
147 * driver may use this to determine if there is controller-specific
148 * data wrapped around this struct. Drivers of platform code that sets
149 * the dma_dev field must therefore make sure to use an appropriate
150 * controller-specific dma slave structure wrapping this struct.
151 */
152struct dma_slave {
153 struct device *dev;
154 struct device *dma_dev;
155 dma_addr_t tx_reg;
156 dma_addr_t rx_reg;
157 enum dma_slave_width reg_width;
158};
159
160/**
122 * struct dma_chan_percpu - the per-CPU part of struct dma_chan 161 * struct dma_chan_percpu - the per-CPU part of struct dma_chan
123 * @refcount: local_t used for open-coded "bigref" counting 162 * @refcount: local_t used for open-coded "bigref" counting
124 * @memcpy_count: transaction counter 163 * @memcpy_count: transaction counter
@@ -208,11 +247,14 @@ typedef enum dma_state_client (*dma_event_callback) (struct dma_client *client,
208 * @event_callback: func ptr to call when something happens 247 * @event_callback: func ptr to call when something happens
209 * @cap_mask: only return channels that satisfy the requested capabilities 248 * @cap_mask: only return channels that satisfy the requested capabilities
210 * a value of zero corresponds to any capability 249 * a value of zero corresponds to any capability
250 * @slave: data for preparing slave transfer. Must be non-NULL iff the
251 * DMA_SLAVE capability is requested.
211 * @global_node: list_head for global dma_client_list 252 * @global_node: list_head for global dma_client_list
212 */ 253 */
213struct dma_client { 254struct dma_client {
214 dma_event_callback event_callback; 255 dma_event_callback event_callback;
215 dma_cap_mask_t cap_mask; 256 dma_cap_mask_t cap_mask;
257 struct dma_slave *slave;
216 struct list_head global_node; 258 struct list_head global_node;
217}; 259};
218 260
@@ -269,6 +311,8 @@ struct dma_async_tx_descriptor {
269 * @device_prep_dma_zero_sum: prepares a zero_sum operation 311 * @device_prep_dma_zero_sum: prepares a zero_sum operation
270 * @device_prep_dma_memset: prepares a memset operation 312 * @device_prep_dma_memset: prepares a memset operation
271 * @device_prep_dma_interrupt: prepares an end of chain interrupt operation 313 * @device_prep_dma_interrupt: prepares an end of chain interrupt operation
314 * @device_prep_slave_sg: prepares a slave dma operation
315 * @device_terminate_all: terminate all pending operations
272 * @device_issue_pending: push pending transactions to hardware 316 * @device_issue_pending: push pending transactions to hardware
273 */ 317 */
274struct dma_device { 318struct dma_device {
@@ -304,6 +348,12 @@ struct dma_device {
304 struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)( 348 struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)(
305 struct dma_chan *chan, unsigned long flags); 349 struct dma_chan *chan, unsigned long flags);
306 350
351 struct dma_async_tx_descriptor *(*device_prep_slave_sg)(
352 struct dma_chan *chan, struct scatterlist *sgl,
353 unsigned int sg_len, enum dma_data_direction direction,
354 unsigned long flags);
355 void (*device_terminate_all)(struct dma_chan *chan);
356
307 enum dma_status (*device_is_tx_complete)(struct dma_chan *chan, 357 enum dma_status (*device_is_tx_complete)(struct dma_chan *chan,
308 dma_cookie_t cookie, dma_cookie_t *last, 358 dma_cookie_t cookie, dma_cookie_t *last,
309 dma_cookie_t *used); 359 dma_cookie_t *used);