diff options
| author | Oleg Matcovschi <oleg.matcovschi@ti.com> | 2012-05-15 17:35:08 -0400 |
|---|---|---|
| committer | Tony Lindgren <tony@atomide.com> | 2012-06-04 01:50:42 -0400 |
| commit | bedfb7adc7f7e2f344b21584905b2357147ba27e (patch) | |
| tree | 6fcfcf879944bb49c190117f7df215e240a871af | |
| parent | f8f5701bdaf9134b1f90e5044a82c66324d2073f (diff) | |
ARM: OMAP: dma: Clear status registers on enable/disable irq
Use omap_disable_channel_irq() function instead of directly accessing CICR
register in various functions.
The omap_disable_chanel_irq() function now clears pending interrupts
and disables interrupt on channel.
Functions omap2_enable_irq_lch()/omap2_disable_irq_lch() clear interrupt
status register.
Signed-off-by: Oleg Matcovschi <oleg.matcovschi@ti.com>
Tested-by: Jarkko Nikula <jarkko.nikula@bitmer.com>
[tony@atomide.com: updated comments to clarify CICR access]
Signed-off-by: Tony Lindgren <tony@atomide.com>
| -rw-r--r-- | arch/arm/plat-omap/dma.c | 59 |
1 files changed, 28 insertions, 31 deletions
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index cb16ade437cb..7fe626761e53 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c | |||
| @@ -573,22 +573,25 @@ EXPORT_SYMBOL(omap_set_dma_dest_burst_mode); | |||
| 573 | 573 | ||
| 574 | static inline void omap_enable_channel_irq(int lch) | 574 | static inline void omap_enable_channel_irq(int lch) |
| 575 | { | 575 | { |
| 576 | u32 status; | ||
| 577 | |||
| 578 | /* Clear CSR */ | 576 | /* Clear CSR */ |
| 579 | if (cpu_class_is_omap1()) | 577 | if (cpu_class_is_omap1()) |
| 580 | status = p->dma_read(CSR, lch); | 578 | p->dma_read(CSR, lch); |
| 581 | else if (cpu_class_is_omap2()) | 579 | else |
| 582 | p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch); | 580 | p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch); |
| 583 | 581 | ||
| 584 | /* Enable some nice interrupts. */ | 582 | /* Enable some nice interrupts. */ |
| 585 | p->dma_write(dma_chan[lch].enabled_irqs, CICR, lch); | 583 | p->dma_write(dma_chan[lch].enabled_irqs, CICR, lch); |
| 586 | } | 584 | } |
| 587 | 585 | ||
| 588 | static void omap_disable_channel_irq(int lch) | 586 | static inline void omap_disable_channel_irq(int lch) |
| 589 | { | 587 | { |
| 590 | if (cpu_class_is_omap2()) | 588 | /* disable channel interrupts */ |
| 591 | p->dma_write(0, CICR, lch); | 589 | p->dma_write(0, CICR, lch); |
| 590 | /* Clear CSR */ | ||
| 591 | if (cpu_class_is_omap1()) | ||
| 592 | p->dma_read(CSR, lch); | ||
| 593 | else | ||
| 594 | p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch); | ||
| 592 | } | 595 | } |
| 593 | 596 | ||
| 594 | void omap_enable_dma_irq(int lch, u16 bits) | 597 | void omap_enable_dma_irq(int lch, u16 bits) |
| @@ -632,14 +635,14 @@ static inline void disable_lnk(int lch) | |||
| 632 | l = p->dma_read(CLNK_CTRL, lch); | 635 | l = p->dma_read(CLNK_CTRL, lch); |
| 633 | 636 | ||
| 634 | /* Disable interrupts */ | 637 | /* Disable interrupts */ |
| 638 | omap_disable_channel_irq(lch); | ||
| 639 | |||
| 635 | if (cpu_class_is_omap1()) { | 640 | if (cpu_class_is_omap1()) { |
| 636 | p->dma_write(0, CICR, lch); | ||
| 637 | /* Set the STOP_LNK bit */ | 641 | /* Set the STOP_LNK bit */ |
| 638 | l |= 1 << 14; | 642 | l |= 1 << 14; |
| 639 | } | 643 | } |
| 640 | 644 | ||
| 641 | if (cpu_class_is_omap2()) { | 645 | if (cpu_class_is_omap2()) { |
| 642 | omap_disable_channel_irq(lch); | ||
| 643 | /* Clear the ENABLE_LNK bit */ | 646 | /* Clear the ENABLE_LNK bit */ |
| 644 | l &= ~(1 << 15); | 647 | l &= ~(1 << 15); |
| 645 | } | 648 | } |
| @@ -657,6 +660,9 @@ static inline void omap2_enable_irq_lch(int lch) | |||
| 657 | return; | 660 | return; |
| 658 | 661 | ||
| 659 | spin_lock_irqsave(&dma_chan_lock, flags); | 662 | spin_lock_irqsave(&dma_chan_lock, flags); |
| 663 | /* clear IRQ STATUS */ | ||
| 664 | p->dma_write(1 << lch, IRQSTATUS_L0, lch); | ||
| 665 | /* Enable interrupt */ | ||
| 660 | val = p->dma_read(IRQENABLE_L0, lch); | 666 | val = p->dma_read(IRQENABLE_L0, lch); |
| 661 | val |= 1 << lch; | 667 | val |= 1 << lch; |
| 662 | p->dma_write(val, IRQENABLE_L0, lch); | 668 | p->dma_write(val, IRQENABLE_L0, lch); |
| @@ -672,9 +678,12 @@ static inline void omap2_disable_irq_lch(int lch) | |||
| 672 | return; | 678 | return; |
| 673 | 679 | ||
| 674 | spin_lock_irqsave(&dma_chan_lock, flags); | 680 | spin_lock_irqsave(&dma_chan_lock, flags); |
| 681 | /* Disable interrupt */ | ||
| 675 | val = p->dma_read(IRQENABLE_L0, lch); | 682 | val = p->dma_read(IRQENABLE_L0, lch); |
| 676 | val &= ~(1 << lch); | 683 | val &= ~(1 << lch); |
| 677 | p->dma_write(val, IRQENABLE_L0, lch); | 684 | p->dma_write(val, IRQENABLE_L0, lch); |
| 685 | /* clear IRQ STATUS */ | ||
| 686 | p->dma_write(1 << lch, IRQSTATUS_L0, lch); | ||
| 678 | spin_unlock_irqrestore(&dma_chan_lock, flags); | 687 | spin_unlock_irqrestore(&dma_chan_lock, flags); |
| 679 | } | 688 | } |
| 680 | 689 | ||
| @@ -745,11 +754,8 @@ int omap_request_dma(int dev_id, const char *dev_name, | |||
| 745 | } | 754 | } |
| 746 | 755 | ||
| 747 | if (cpu_class_is_omap2()) { | 756 | if (cpu_class_is_omap2()) { |
| 748 | omap2_enable_irq_lch(free_ch); | ||
| 749 | omap_enable_channel_irq(free_ch); | 757 | omap_enable_channel_irq(free_ch); |
| 750 | /* Clear the CSR register and IRQ status register */ | 758 | omap2_enable_irq_lch(free_ch); |
| 751 | p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, free_ch); | ||
| 752 | p->dma_write(1 << free_ch, IRQSTATUS_L0, 0); | ||
| 753 | } | 759 | } |
| 754 | 760 | ||
| 755 | *dma_ch_out = free_ch; | 761 | *dma_ch_out = free_ch; |
| @@ -768,27 +774,19 @@ void omap_free_dma(int lch) | |||
| 768 | return; | 774 | return; |
| 769 | } | 775 | } |
| 770 | 776 | ||
| 771 | if (cpu_class_is_omap1()) { | 777 | /* Disable interrupt for logical channel */ |
| 772 | /* Disable all DMA interrupts for the channel. */ | 778 | if (cpu_class_is_omap2()) |
| 773 | p->dma_write(0, CICR, lch); | ||
| 774 | /* Make sure the DMA transfer is stopped. */ | ||
| 775 | p->dma_write(0, CCR, lch); | ||
| 776 | } | ||
| 777 | |||
| 778 | if (cpu_class_is_omap2()) { | ||
| 779 | omap2_disable_irq_lch(lch); | 779 | omap2_disable_irq_lch(lch); |
| 780 | 780 | ||
| 781 | /* Clear the CSR register and IRQ status register */ | 781 | /* Disable all DMA interrupts for the channel. */ |
| 782 | p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch); | 782 | omap_disable_channel_irq(lch); |
| 783 | p->dma_write(1 << lch, IRQSTATUS_L0, lch); | ||
| 784 | 783 | ||
| 785 | /* Disable all DMA interrupts for the channel. */ | 784 | /* Make sure the DMA transfer is stopped. */ |
| 786 | p->dma_write(0, CICR, lch); | 785 | p->dma_write(0, CCR, lch); |
| 787 | 786 | ||
| 788 | /* Make sure the DMA transfer is stopped. */ | 787 | /* Clear registers */ |
| 789 | p->dma_write(0, CCR, lch); | 788 | if (cpu_class_is_omap2()) |
| 790 | omap_clear_dma(lch); | 789 | omap_clear_dma(lch); |
| 791 | } | ||
| 792 | 790 | ||
| 793 | spin_lock_irqsave(&dma_chan_lock, flags); | 791 | spin_lock_irqsave(&dma_chan_lock, flags); |
| 794 | dma_chan[lch].dev_id = -1; | 792 | dma_chan[lch].dev_id = -1; |
| @@ -943,8 +941,7 @@ void omap_stop_dma(int lch) | |||
| 943 | u32 l; | 941 | u32 l; |
| 944 | 942 | ||
| 945 | /* Disable all interrupts on the channel */ | 943 | /* Disable all interrupts on the channel */ |
| 946 | if (cpu_class_is_omap1()) | 944 | omap_disable_channel_irq(lch); |
| 947 | p->dma_write(0, CICR, lch); | ||
| 948 | 945 | ||
| 949 | l = p->dma_read(CCR, lch); | 946 | l = p->dma_read(CCR, lch); |
| 950 | if (IS_DMA_ERRATA(DMA_ERRATA_i541) && | 947 | if (IS_DMA_ERRATA(DMA_ERRATA_i541) && |
