summaryrefslogtreecommitdiffstats
path: root/drivers/rapidio/devices/tsi721_dma.c
diff options
context:
space:
mode:
authorAlexandre Bounine <alexandre.bounine@idt.com>2016-03-22 22:26:23 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-22 23:36:02 +0100
commit748353cc2d03d0514a3bf6d0752244ce657f197c (patch)
treeadd9bf2705e262905ad3486d2b41dfed6fe61277 /drivers/rapidio/devices/tsi721_dma.c
parentrapidio: add core mport removal support (diff)
downloadlinux-748353cc2d03d0514a3bf6d0752244ce657f197c.tar.xz
linux-748353cc2d03d0514a3bf6d0752244ce657f197c.zip
rapidio/tsi721: add HW specific mport removal
Add hardware-specific device removal support for Tsi721 PCIe-to-RapidIO bridge. To avoid excessive data type conversions, parameters passed to some internal functions have been revised. Dynamic memory allocations of rio_mport and rio_ops have been replaced to reduce references between data structures. Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com> Cc: Matt Porter <mporter@kernel.crashing.org> Cc: Aurelien Jacquiot <a-jacquiot@ti.com> Cc: Andre van Herk <andre.van.herk@prodrive-technologies.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rapidio/devices/tsi721_dma.c')
-rw-r--r--drivers/rapidio/devices/tsi721_dma.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/rapidio/devices/tsi721_dma.c b/drivers/rapidio/devices/tsi721_dma.c
index b490ec36f018..31bb61b43c3f 100644
--- a/drivers/rapidio/devices/tsi721_dma.c
+++ b/drivers/rapidio/devices/tsi721_dma.c
@@ -887,7 +887,7 @@ int tsi721_register_dma(struct tsi721_device *priv)
int i;
int nr_channels = 0;
int err;
- struct rio_mport *mport = priv->mport;
+ struct rio_mport *mport = &priv->mport;
INIT_LIST_HEAD(&mport->dma.channels);
@@ -937,3 +937,29 @@ int tsi721_register_dma(struct tsi721_device *priv)
return err;
}
+
+void tsi721_unregister_dma(struct tsi721_device *priv)
+{
+ struct rio_mport *mport = &priv->mport;
+ struct dma_chan *chan, *_c;
+ struct tsi721_bdma_chan *bdma_chan;
+
+ tsi721_dma_stop_all(priv);
+ dma_async_device_unregister(&mport->dma);
+
+ list_for_each_entry_safe(chan, _c, &mport->dma.channels,
+ device_node) {
+ bdma_chan = to_tsi721_chan(chan);
+ if (bdma_chan->active) {
+ tsi721_bdma_interrupt_enable(bdma_chan, 0);
+ bdma_chan->active = false;
+ tsi721_sync_dma_irq(bdma_chan);
+ tasklet_kill(&bdma_chan->tasklet);
+ INIT_LIST_HEAD(&bdma_chan->free_list);
+ kfree(bdma_chan->tx_desc);
+ tsi721_bdma_ch_free(bdma_chan);
+ }
+
+ list_del(&chan->device_node);
+ }
+}