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 /drivers/rapidio | |
| 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 'drivers/rapidio')
| -rw-r--r-- | drivers/rapidio/Kconfig | 14 | ||||
| -rw-r--r-- | drivers/rapidio/rio.c | 81 |
2 files changed, 95 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 | ||
| 25 | config 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 | |||
| 25 | config RAPIDIO_DEBUG | 39 | config 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 | |||
| 1126 | static 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 | */ | ||
| 1142 | struct 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 | } | ||
| 1153 | EXPORT_SYMBOL_GPL(rio_request_dma); | ||
| 1154 | |||
| 1155 | /** | ||
| 1156 | * rio_release_dma - release specified DMA channel | ||
| 1157 | * @dchan: DMA channel to release | ||
| 1158 | */ | ||
| 1159 | void rio_release_dma(struct dma_chan *dchan) | ||
| 1160 | { | ||
| 1161 | dma_release_channel(dchan); | ||
| 1162 | } | ||
| 1163 | EXPORT_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 | */ | ||
| 1179 | struct 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 | } | ||
| 1201 | EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg); | ||
| 1202 | |||
| 1203 | #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ | ||
| 1204 | |||
| 1124 | static void rio_fixup_device(struct rio_dev *dev) | 1205 | static void rio_fixup_device(struct rio_dev *dev) |
| 1125 | { | 1206 | { |
| 1126 | } | 1207 | } |
