aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Bounine <alexandre.bounine@idt.com>2012-05-31 19:26:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-31 20:49:31 -0400
commite42d98ebe7d754a2c9fbccd6186721d3ca8679f6 (patch)
treeeed734672410f2eb8fab07fbd14f88bfaf8a882f
parentce2d52cc1364a22fc1a161781e60ee3cbb499a6d (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>
-rw-r--r--drivers/rapidio/Kconfig14
-rw-r--r--drivers/rapidio/rio.c81
-rw-r--r--include/linux/dmaengine.h12
-rw-r--r--include/linux/rio.h47
-rw-r--r--include/linux/rio_drv.h9
5 files changed, 163 insertions, 0 deletions
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index bc8719238793..6194d35ebb97 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -22,6 +22,20 @@ config RAPIDIO_ENABLE_RX_TX_PORTS
22 ports for Input/Output direction to allow other traffic 22 ports for Input/Output direction to allow other traffic
23 than Maintenance transfers. 23 than Maintenance transfers.
24 24
25config RAPIDIO_DMA_ENGINE
26 bool "DMA Engine support for RapidIO"
27 depends on RAPIDIO
28 select DMADEVICES
29 select DMA_ENGINE
30 help
31 Say Y here if you want to use DMA Engine frameork for RapidIO data
32 transfers to/from target RIO devices. RapidIO uses NREAD and
33 NWRITE (NWRITE_R, SWRITE) requests to transfer data between local
34 memory and memory on remote target device. You need a DMA controller
35 capable to perform data transfers to/from RapidIO.
36
37 If you are unsure about this, say Y here.
38
25config RAPIDIO_DEBUG 39config RAPIDIO_DEBUG
26 bool "RapidIO subsystem debug messages" 40 bool "RapidIO subsystem debug messages"
27 depends on RAPIDIO 41 depends on RAPIDIO
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 86c9a091a2ff..c40665a4fa33 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -1121,6 +1121,87 @@ int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
1121 return 0; 1121 return 0;
1122} 1122}
1123 1123
1124#ifdef CONFIG_RAPIDIO_DMA_ENGINE
1125
1126static bool rio_chan_filter(struct dma_chan *chan, void *arg)
1127{
1128 struct rio_dev *rdev = arg;
1129
1130 /* Check that DMA device belongs to the right MPORT */
1131 return (rdev->net->hport ==
1132 container_of(chan->device, struct rio_mport, dma));
1133}
1134
1135/**
1136 * rio_request_dma - request RapidIO capable DMA channel that supports
1137 * specified target RapidIO device.
1138 * @rdev: RIO device control structure
1139 *
1140 * Returns pointer to allocated DMA channel or NULL if failed.
1141 */
1142struct dma_chan *rio_request_dma(struct rio_dev *rdev)
1143{
1144 dma_cap_mask_t mask;
1145 struct dma_chan *dchan;
1146
1147 dma_cap_zero(mask);
1148 dma_cap_set(DMA_SLAVE, mask);
1149 dchan = dma_request_channel(mask, rio_chan_filter, rdev);
1150
1151 return dchan;
1152}
1153EXPORT_SYMBOL_GPL(rio_request_dma);
1154
1155/**
1156 * rio_release_dma - release specified DMA channel
1157 * @dchan: DMA channel to release
1158 */
1159void rio_release_dma(struct dma_chan *dchan)
1160{
1161 dma_release_channel(dchan);
1162}
1163EXPORT_SYMBOL_GPL(rio_release_dma);
1164
1165/**
1166 * rio_dma_prep_slave_sg - RapidIO specific wrapper
1167 * for device_prep_slave_sg callback defined by DMAENGINE.
1168 * @rdev: RIO device control structure
1169 * @dchan: DMA channel to configure
1170 * @data: RIO specific data descriptor
1171 * @direction: DMA data transfer direction (TO or FROM the device)
1172 * @flags: dmaengine defined flags
1173 *
1174 * Initializes RapidIO capable DMA channel for the specified data transfer.
1175 * Uses DMA channel private extension to pass information related to remote
1176 * target RIO device.
1177 * Returns pointer to DMA transaction descriptor or NULL if failed.
1178 */
1179struct dma_async_tx_descriptor *rio_dma_prep_slave_sg(struct rio_dev *rdev,
1180 struct dma_chan *dchan, struct rio_dma_data *data,
1181 enum dma_transfer_direction direction, unsigned long flags)
1182{
1183 struct dma_async_tx_descriptor *txd = NULL;
1184 struct rio_dma_ext rio_ext;
1185
1186 if (dchan->device->device_prep_slave_sg == NULL) {
1187 pr_err("%s: prep_rio_sg == NULL\n", __func__);
1188 return NULL;
1189 }
1190
1191 rio_ext.destid = rdev->destid;
1192 rio_ext.rio_addr_u = data->rio_addr_u;
1193 rio_ext.rio_addr = data->rio_addr;
1194 rio_ext.wr_type = data->wr_type;
1195
1196 txd = dmaengine_prep_rio_sg(dchan, data->sg, data->sg_len,
1197 direction, flags, &rio_ext);
1198
1199 return txd;
1200}
1201EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg);
1202
1203#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
1204
1124static void rio_fixup_device(struct rio_dev *dev) 1205static void rio_fixup_device(struct rio_dev *dev)
1125{ 1206{
1126} 1207}
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
639struct rio_dma_ext;
640static 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
638static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic( 650static 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 */
415enum 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
422struct 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
429struct 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
439static 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 */
399extern int rio_register_mport(struct rio_mport *); 446extern int rio_register_mport(struct rio_mport *);
400extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int); 447extern 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 *);
377struct rio_dev *rio_dev_get(struct rio_dev *); 377struct rio_dev *rio_dev_get(struct rio_dev *);
378void rio_dev_put(struct rio_dev *); 378void rio_dev_put(struct rio_dev *);
379 379
380#ifdef CONFIG_RAPIDIO_DMA_ENGINE
381extern struct dma_chan *rio_request_dma(struct rio_dev *rdev);
382extern void rio_release_dma(struct dma_chan *dchan);
383extern 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