diff options
| author | Alexandre Bounine <alexandre.bounine@idt.com> | 2012-05-31 19:26:38 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-31 20:49:31 -0400 |
| commit | e42d98ebe7d754a2c9fbccd6186721d3ca8679f6 (patch) | |
| tree | eed734672410f2eb8fab07fbd14f88bfaf8a882f /include/linux | |
| parent | ce2d52cc1364a22fc1a161781e60ee3cbb499a6d (diff) | |
rapidio: add DMA engine support for RIO data transfers
Adds DMA Engine framework support into RapidIO subsystem.
Uses DMA Engine DMA_SLAVE interface to generate data transfers to/from
remote RapidIO target devices.
Introduces RapidIO-specific wrapper for prep_slave_sg() interface with an
extra parameter to pass target specific information.
Uses scatterlist to describe local data buffer. Address flat data buffer
on a remote side.
Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Acked-by: Vinod Koul <vinod.koul@linux.intel.com>
Cc: Li Yang <leoli@freescale.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/dmaengine.h | 12 | ||||
| -rw-r--r-- | include/linux/rio.h | 47 | ||||
| -rw-r--r-- | include/linux/rio_drv.h | 9 |
3 files changed, 68 insertions, 0 deletions
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index d3fec584e8c3..56377df39124 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h | |||
| @@ -635,6 +635,18 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_sg( | |||
| 635 | dir, flags, NULL); | 635 | dir, flags, NULL); |
| 636 | } | 636 | } |
| 637 | 637 | ||
| 638 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | ||
| 639 | struct rio_dma_ext; | ||
| 640 | static inline struct dma_async_tx_descriptor *dmaengine_prep_rio_sg( | ||
| 641 | struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, | ||
| 642 | enum dma_transfer_direction dir, unsigned long flags, | ||
| 643 | struct rio_dma_ext *rio_ext) | ||
| 644 | { | ||
| 645 | return chan->device->device_prep_slave_sg(chan, sgl, sg_len, | ||
| 646 | dir, flags, rio_ext); | ||
| 647 | } | ||
| 648 | #endif | ||
| 649 | |||
| 638 | static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic( | 650 | static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic( |
| 639 | struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, | 651 | struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, |
| 640 | size_t period_len, enum dma_transfer_direction dir) | 652 | size_t period_len, enum dma_transfer_direction dir) |
diff --git a/include/linux/rio.h b/include/linux/rio.h index 4d50611112ba..a90ebadd9da0 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h | |||
| @@ -20,6 +20,9 @@ | |||
| 20 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
| 21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
| 22 | #include <linux/rio_regs.h> | 22 | #include <linux/rio_regs.h> |
| 23 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | ||
| 24 | #include <linux/dmaengine.h> | ||
| 25 | #endif | ||
| 23 | 26 | ||
| 24 | #define RIO_NO_HOPCOUNT -1 | 27 | #define RIO_NO_HOPCOUNT -1 |
| 25 | #define RIO_INVALID_DESTID 0xffff | 28 | #define RIO_INVALID_DESTID 0xffff |
| @@ -254,6 +257,9 @@ struct rio_mport { | |||
| 254 | u32 phys_efptr; | 257 | u32 phys_efptr; |
| 255 | unsigned char name[40]; | 258 | unsigned char name[40]; |
| 256 | void *priv; /* Master port private data */ | 259 | void *priv; /* Master port private data */ |
| 260 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | ||
| 261 | struct dma_device dma; | ||
| 262 | #endif | ||
| 257 | }; | 263 | }; |
| 258 | 264 | ||
| 259 | /** | 265 | /** |
| @@ -395,6 +401,47 @@ union rio_pw_msg { | |||
| 395 | u32 raw[RIO_PW_MSG_SIZE/sizeof(u32)]; | 401 | u32 raw[RIO_PW_MSG_SIZE/sizeof(u32)]; |
| 396 | }; | 402 | }; |
| 397 | 403 | ||
| 404 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | ||
| 405 | |||
| 406 | /** | ||
| 407 | * enum rio_write_type - RIO write transaction types used in DMA transfers | ||
| 408 | * | ||
| 409 | * Note: RapidIO specification defines write (NWRITE) and | ||
| 410 | * write-with-response (NWRITE_R) data transfer operations. | ||
| 411 | * Existing DMA controllers that service RapidIO may use one of these operations | ||
| 412 | * for entire data transfer or their combination with only the last data packet | ||
| 413 | * requires response. | ||
| 414 | */ | ||
| 415 | enum rio_write_type { | ||
| 416 | RDW_DEFAULT, /* default method used by DMA driver */ | ||
| 417 | RDW_ALL_NWRITE, /* all packets use NWRITE */ | ||
| 418 | RDW_ALL_NWRITE_R, /* all packets use NWRITE_R */ | ||
| 419 | RDW_LAST_NWRITE_R, /* last packet uses NWRITE_R, others - NWRITE */ | ||
| 420 | }; | ||
| 421 | |||
| 422 | struct rio_dma_ext { | ||
| 423 | u16 destid; | ||
| 424 | u64 rio_addr; /* low 64-bits of 66-bit RapidIO address */ | ||
| 425 | u8 rio_addr_u; /* upper 2-bits of 66-bit RapidIO address */ | ||
| 426 | enum rio_write_type wr_type; /* preferred RIO write operation type */ | ||
| 427 | }; | ||
| 428 | |||
| 429 | struct rio_dma_data { | ||
| 430 | /* Local data (as scatterlist) */ | ||
| 431 | struct scatterlist *sg; /* I/O scatter list */ | ||
| 432 | unsigned int sg_len; /* size of scatter list */ | ||
| 433 | /* Remote device address (flat buffer) */ | ||
| 434 | u64 rio_addr; /* low 64-bits of 66-bit RapidIO address */ | ||
| 435 | u8 rio_addr_u; /* upper 2-bits of 66-bit RapidIO address */ | ||
| 436 | enum rio_write_type wr_type; /* preferred RIO write operation type */ | ||
| 437 | }; | ||
| 438 | |||
| 439 | static inline struct rio_mport *dma_to_mport(struct dma_device *ddev) | ||
| 440 | { | ||
| 441 | return container_of(ddev, struct rio_mport, dma); | ||
| 442 | } | ||
| 443 | #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ | ||
| 444 | |||
| 398 | /* Architecture and hardware-specific functions */ | 445 | /* Architecture and hardware-specific functions */ |
| 399 | extern int rio_register_mport(struct rio_mport *); | 446 | extern int rio_register_mport(struct rio_mport *); |
| 400 | extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int); | 447 | extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int); |
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h index 7f07470e1ed9..31ad146be316 100644 --- a/include/linux/rio_drv.h +++ b/include/linux/rio_drv.h | |||
| @@ -377,6 +377,15 @@ void rio_unregister_driver(struct rio_driver *); | |||
| 377 | struct rio_dev *rio_dev_get(struct rio_dev *); | 377 | struct rio_dev *rio_dev_get(struct rio_dev *); |
| 378 | void rio_dev_put(struct rio_dev *); | 378 | void rio_dev_put(struct rio_dev *); |
| 379 | 379 | ||
| 380 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | ||
| 381 | extern struct dma_chan *rio_request_dma(struct rio_dev *rdev); | ||
| 382 | extern void rio_release_dma(struct dma_chan *dchan); | ||
| 383 | extern struct dma_async_tx_descriptor *rio_dma_prep_slave_sg( | ||
| 384 | struct rio_dev *rdev, struct dma_chan *dchan, | ||
| 385 | struct rio_dma_data *data, | ||
| 386 | enum dma_transfer_direction direction, unsigned long flags); | ||
| 387 | #endif | ||
| 388 | |||
| 380 | /** | 389 | /** |
| 381 | * rio_name - Get the unique RIO device identifier | 390 | * rio_name - Get the unique RIO device identifier |
| 382 | * @rdev: RIO device | 391 | * @rdev: RIO device |
