aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Bounine <alexandre.bounine@idt.com>2016-03-22 17:26:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-22 18:36:02 -0400
commite3dd8cd4778ebc75c654f73d8673281078c81ed9 (patch)
tree361fad4c972f69069d9815f45a184a0a4a74bf5e
parent83dc2cbc1136108068637d5c98636647f7b82461 (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.c15
-rw-r--r--drivers/rapidio/devices/tsi721.h3
-rw-r--r--drivers/rapidio/devices/tsi721_dma.c30
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
2643err_free_consistent: 2645err_free_consistent:
@@ -2660,6 +2662,18 @@ err_exit:
2660 return err; 2662 return err;
2661} 2663}
2662 2664
2665static 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
2663static const struct pci_device_id tsi721_pci_tbl[] = { 2677static 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
2676static int __init tsi721_init(void) 2691static 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
867extern void tsi721_bdma_handler(struct tsi721_bdma_chan *bdma_chan); 867extern void tsi721_bdma_handler(struct tsi721_bdma_chan *bdma_chan);
868extern int tsi721_register_dma(struct tsi721_device *priv); 868extern int tsi721_register_dma(struct tsi721_device *priv);
869extern 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
855static 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
875void 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
855int tsi721_register_dma(struct tsi721_device *priv) 885int tsi721_register_dma(struct tsi721_device *priv)
856{ 886{
857 int i; 887 int i;