diff options
author | Alexandre Bounine <alexandre.bounine@idt.com> | 2016-03-22 17:26:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-22 18:36:02 -0400 |
commit | e3dd8cd4778ebc75c654f73d8673281078c81ed9 (patch) | |
tree | 361fad4c972f69069d9815f45a184a0a4a74bf5e | |
parent | 83dc2cbc1136108068637d5c98636647f7b82461 (diff) |
rapidio/tsi721: add shutdown notification callback
Add device driver specific shutdown notification callback.
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>
-rw-r--r-- | drivers/rapidio/devices/tsi721.c | 15 | ||||
-rw-r--r-- | drivers/rapidio/devices/tsi721.h | 3 | ||||
-rw-r--r-- | drivers/rapidio/devices/tsi721_dma.c | 30 |
3 files changed, 48 insertions, 0 deletions
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index cd40f0f9fbfe..1fc9663ae3b5 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c | |||
@@ -2638,6 +2638,8 @@ static int tsi721_probe(struct pci_dev *pdev, | |||
2638 | if (err) | 2638 | if (err) |
2639 | goto err_free_consistent; | 2639 | goto err_free_consistent; |
2640 | 2640 | ||
2641 | pci_set_drvdata(pdev, priv); | ||
2642 | |||
2641 | return 0; | 2643 | return 0; |
2642 | 2644 | ||
2643 | err_free_consistent: | 2645 | err_free_consistent: |
@@ -2660,6 +2662,18 @@ err_exit: | |||
2660 | return err; | 2662 | return err; |
2661 | } | 2663 | } |
2662 | 2664 | ||
2665 | static void tsi721_shutdown(struct pci_dev *pdev) | ||
2666 | { | ||
2667 | struct tsi721_device *priv = pci_get_drvdata(pdev); | ||
2668 | |||
2669 | dev_dbg(&pdev->dev, "RIO: %s\n", __func__); | ||
2670 | |||
2671 | tsi721_disable_ints(priv); | ||
2672 | tsi721_dma_stop_all(priv); | ||
2673 | pci_clear_master(pdev); | ||
2674 | pci_disable_device(pdev); | ||
2675 | } | ||
2676 | |||
2663 | static const struct pci_device_id tsi721_pci_tbl[] = { | 2677 | static const struct pci_device_id tsi721_pci_tbl[] = { |
2664 | { PCI_DEVICE(PCI_VENDOR_ID_IDT, PCI_DEVICE_ID_TSI721) }, | 2678 | { PCI_DEVICE(PCI_VENDOR_ID_IDT, PCI_DEVICE_ID_TSI721) }, |
2665 | { 0, } /* terminate list */ | 2679 | { 0, } /* terminate list */ |
@@ -2671,6 +2685,7 @@ static struct pci_driver tsi721_driver = { | |||
2671 | .name = "tsi721", | 2685 | .name = "tsi721", |
2672 | .id_table = tsi721_pci_tbl, | 2686 | .id_table = tsi721_pci_tbl, |
2673 | .probe = tsi721_probe, | 2687 | .probe = tsi721_probe, |
2688 | .shutdown = tsi721_shutdown, | ||
2674 | }; | 2689 | }; |
2675 | 2690 | ||
2676 | static int __init tsi721_init(void) | 2691 | static int __init tsi721_init(void) |
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h index d675a44ffc17..ce2fb1193869 100644 --- a/drivers/rapidio/devices/tsi721.h +++ b/drivers/rapidio/devices/tsi721.h | |||
@@ -866,6 +866,9 @@ struct tsi721_device { | |||
866 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | 866 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE |
867 | extern void tsi721_bdma_handler(struct tsi721_bdma_chan *bdma_chan); | 867 | extern void tsi721_bdma_handler(struct tsi721_bdma_chan *bdma_chan); |
868 | extern int tsi721_register_dma(struct tsi721_device *priv); | 868 | extern int tsi721_register_dma(struct tsi721_device *priv); |
869 | extern void tsi721_dma_stop_all(struct tsi721_device *priv); | ||
870 | #else | ||
871 | #define tsi721_dma_stop_all(priv) do {} while (0) | ||
869 | #endif | 872 | #endif |
870 | 873 | ||
871 | #endif | 874 | #endif |
diff --git a/drivers/rapidio/devices/tsi721_dma.c b/drivers/rapidio/devices/tsi721_dma.c index 500e1e044c36..b490ec36f018 100644 --- a/drivers/rapidio/devices/tsi721_dma.c +++ b/drivers/rapidio/devices/tsi721_dma.c | |||
@@ -852,6 +852,36 @@ static int tsi721_terminate_all(struct dma_chan *dchan) | |||
852 | return 0; | 852 | return 0; |
853 | } | 853 | } |
854 | 854 | ||
855 | static void tsi721_dma_stop(struct tsi721_bdma_chan *bdma_chan) | ||
856 | { | ||
857 | if (!bdma_chan->active) | ||
858 | return; | ||
859 | spin_lock_bh(&bdma_chan->lock); | ||
860 | if (!tsi721_dma_is_idle(bdma_chan)) { | ||
861 | int timeout = 100000; | ||
862 | |||
863 | /* stop the transfer in progress */ | ||
864 | iowrite32(TSI721_DMAC_CTL_SUSP, | ||
865 | bdma_chan->regs + TSI721_DMAC_CTL); | ||
866 | |||
867 | /* Wait until DMA channel stops */ | ||
868 | while (!tsi721_dma_is_idle(bdma_chan) && --timeout) | ||
869 | udelay(1); | ||
870 | } | ||
871 | |||
872 | spin_unlock_bh(&bdma_chan->lock); | ||
873 | } | ||
874 | |||
875 | void tsi721_dma_stop_all(struct tsi721_device *priv) | ||
876 | { | ||
877 | int i; | ||
878 | |||
879 | for (i = 0; i < TSI721_DMA_MAXCH; i++) { | ||
880 | if (i != TSI721_DMACH_MAINT) | ||
881 | tsi721_dma_stop(&priv->bdma[i]); | ||
882 | } | ||
883 | } | ||
884 | |||
855 | int tsi721_register_dma(struct tsi721_device *priv) | 885 | int tsi721_register_dma(struct tsi721_device *priv) |
856 | { | 886 | { |
857 | int i; | 887 | int i; |