diff options
Diffstat (limited to 'drivers/rapidio')
-rw-r--r-- | drivers/rapidio/devices/tsi721.h | 1 | ||||
-rw-r--r-- | drivers/rapidio/devices/tsi721_dma.c | 27 |
2 files changed, 19 insertions, 9 deletions
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h index b4b0d83f9ef6..7061ac0ad428 100644 --- a/drivers/rapidio/devices/tsi721.h +++ b/drivers/rapidio/devices/tsi721.h | |||
@@ -678,6 +678,7 @@ struct tsi721_bdma_chan { | |||
678 | struct list_head free_list; | 678 | struct list_head free_list; |
679 | dma_cookie_t completed_cookie; | 679 | dma_cookie_t completed_cookie; |
680 | struct tasklet_struct tasklet; | 680 | struct tasklet_struct tasklet; |
681 | bool active; | ||
681 | }; | 682 | }; |
682 | 683 | ||
683 | #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ | 684 | #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ |
diff --git a/drivers/rapidio/devices/tsi721_dma.c b/drivers/rapidio/devices/tsi721_dma.c index 502663f5f7c6..91245f5dbe81 100644 --- a/drivers/rapidio/devices/tsi721_dma.c +++ b/drivers/rapidio/devices/tsi721_dma.c | |||
@@ -206,8 +206,8 @@ void tsi721_bdma_handler(struct tsi721_bdma_chan *bdma_chan) | |||
206 | { | 206 | { |
207 | /* Disable BDMA channel interrupts */ | 207 | /* Disable BDMA channel interrupts */ |
208 | iowrite32(0, bdma_chan->regs + TSI721_DMAC_INTE); | 208 | iowrite32(0, bdma_chan->regs + TSI721_DMAC_INTE); |
209 | 209 | if (bdma_chan->active) | |
210 | tasklet_schedule(&bdma_chan->tasklet); | 210 | tasklet_schedule(&bdma_chan->tasklet); |
211 | } | 211 | } |
212 | 212 | ||
213 | #ifdef CONFIG_PCI_MSI | 213 | #ifdef CONFIG_PCI_MSI |
@@ -562,7 +562,7 @@ static int tsi721_alloc_chan_resources(struct dma_chan *dchan) | |||
562 | } | 562 | } |
563 | #endif /* CONFIG_PCI_MSI */ | 563 | #endif /* CONFIG_PCI_MSI */ |
564 | 564 | ||
565 | tasklet_enable(&bdma_chan->tasklet); | 565 | bdma_chan->active = true; |
566 | tsi721_bdma_interrupt_enable(bdma_chan, 1); | 566 | tsi721_bdma_interrupt_enable(bdma_chan, 1); |
567 | 567 | ||
568 | return bdma_chan->bd_num - 1; | 568 | return bdma_chan->bd_num - 1; |
@@ -576,9 +576,7 @@ err_out: | |||
576 | static void tsi721_free_chan_resources(struct dma_chan *dchan) | 576 | static void tsi721_free_chan_resources(struct dma_chan *dchan) |
577 | { | 577 | { |
578 | struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan); | 578 | struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan); |
579 | #ifdef CONFIG_PCI_MSI | ||
580 | struct tsi721_device *priv = to_tsi721(dchan->device); | 579 | struct tsi721_device *priv = to_tsi721(dchan->device); |
581 | #endif | ||
582 | LIST_HEAD(list); | 580 | LIST_HEAD(list); |
583 | 581 | ||
584 | dev_dbg(dchan->device->dev, "%s: Entry\n", __func__); | 582 | dev_dbg(dchan->device->dev, "%s: Entry\n", __func__); |
@@ -589,14 +587,25 @@ static void tsi721_free_chan_resources(struct dma_chan *dchan) | |||
589 | BUG_ON(!list_empty(&bdma_chan->active_list)); | 587 | BUG_ON(!list_empty(&bdma_chan->active_list)); |
590 | BUG_ON(!list_empty(&bdma_chan->queue)); | 588 | BUG_ON(!list_empty(&bdma_chan->queue)); |
591 | 589 | ||
592 | tasklet_disable(&bdma_chan->tasklet); | 590 | tsi721_bdma_interrupt_enable(bdma_chan, 0); |
591 | bdma_chan->active = false; | ||
592 | |||
593 | #ifdef CONFIG_PCI_MSI | ||
594 | if (priv->flags & TSI721_USING_MSIX) { | ||
595 | synchronize_irq(priv->msix[TSI721_VECT_DMA0_DONE + | ||
596 | bdma_chan->id].vector); | ||
597 | synchronize_irq(priv->msix[TSI721_VECT_DMA0_INT + | ||
598 | bdma_chan->id].vector); | ||
599 | } else | ||
600 | #endif | ||
601 | synchronize_irq(priv->pdev->irq); | ||
602 | |||
603 | tasklet_kill(&bdma_chan->tasklet); | ||
593 | 604 | ||
594 | spin_lock_bh(&bdma_chan->lock); | 605 | spin_lock_bh(&bdma_chan->lock); |
595 | list_splice_init(&bdma_chan->free_list, &list); | 606 | list_splice_init(&bdma_chan->free_list, &list); |
596 | spin_unlock_bh(&bdma_chan->lock); | 607 | spin_unlock_bh(&bdma_chan->lock); |
597 | 608 | ||
598 | tsi721_bdma_interrupt_enable(bdma_chan, 0); | ||
599 | |||
600 | #ifdef CONFIG_PCI_MSI | 609 | #ifdef CONFIG_PCI_MSI |
601 | if (priv->flags & TSI721_USING_MSIX) { | 610 | if (priv->flags & TSI721_USING_MSIX) { |
602 | free_irq(priv->msix[TSI721_VECT_DMA0_DONE + | 611 | free_irq(priv->msix[TSI721_VECT_DMA0_DONE + |
@@ -790,6 +799,7 @@ int tsi721_register_dma(struct tsi721_device *priv) | |||
790 | bdma_chan->dchan.cookie = 1; | 799 | bdma_chan->dchan.cookie = 1; |
791 | bdma_chan->dchan.chan_id = i; | 800 | bdma_chan->dchan.chan_id = i; |
792 | bdma_chan->id = i; | 801 | bdma_chan->id = i; |
802 | bdma_chan->active = false; | ||
793 | 803 | ||
794 | spin_lock_init(&bdma_chan->lock); | 804 | spin_lock_init(&bdma_chan->lock); |
795 | 805 | ||
@@ -799,7 +809,6 @@ int tsi721_register_dma(struct tsi721_device *priv) | |||
799 | 809 | ||
800 | tasklet_init(&bdma_chan->tasklet, tsi721_dma_tasklet, | 810 | tasklet_init(&bdma_chan->tasklet, tsi721_dma_tasklet, |
801 | (unsigned long)bdma_chan); | 811 | (unsigned long)bdma_chan); |
802 | tasklet_disable(&bdma_chan->tasklet); | ||
803 | list_add_tail(&bdma_chan->dchan.device_node, | 812 | list_add_tail(&bdma_chan->dchan.device_node, |
804 | &mport->dma.channels); | 813 | &mport->dma.channels); |
805 | } | 814 | } |