diff options
author | Alexandre Bounine <alexandre.bounine@idt.com> | 2016-03-22 22:26:23 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-22 23:36:02 +0100 |
commit | 748353cc2d03d0514a3bf6d0752244ce657f197c (patch) | |
tree | add9bf2705e262905ad3486d2b41dfed6fe61277 /drivers/rapidio/devices/tsi721_dma.c | |
parent | rapidio: add core mport removal support (diff) | |
download | linux-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.c | 28 |
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); + } +} |