diff options
Diffstat (limited to 'arch/arm/mach-tegra/dma.c')
-rw-r--r-- | arch/arm/mach-tegra/dma.c | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c index bd4f62a613aa..e945ae28ee77 100644 --- a/arch/arm/mach-tegra/dma.c +++ b/arch/arm/mach-tegra/dma.c | |||
@@ -127,6 +127,7 @@ struct tegra_dma_channel { | |||
127 | 127 | ||
128 | #define NV_DMA_MAX_CHANNELS 32 | 128 | #define NV_DMA_MAX_CHANNELS 32 |
129 | 129 | ||
130 | static bool tegra_dma_initialized; | ||
130 | static DEFINE_MUTEX(tegra_dma_lock); | 131 | static DEFINE_MUTEX(tegra_dma_lock); |
131 | 132 | ||
132 | static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS); | 133 | static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS); |
@@ -352,6 +353,9 @@ struct tegra_dma_channel *tegra_dma_allocate_channel(int mode) | |||
352 | int channel; | 353 | int channel; |
353 | struct tegra_dma_channel *ch = NULL; | 354 | struct tegra_dma_channel *ch = NULL; |
354 | 355 | ||
356 | if (WARN_ON(!tegra_dma_initialized)) | ||
357 | return NULL; | ||
358 | |||
355 | mutex_lock(&tegra_dma_lock); | 359 | mutex_lock(&tegra_dma_lock); |
356 | 360 | ||
357 | /* first channel is the shared channel */ | 361 | /* first channel is the shared channel */ |
@@ -678,6 +682,8 @@ int __init tegra_dma_init(void) | |||
678 | void __iomem *addr; | 682 | void __iomem *addr; |
679 | struct clk *c; | 683 | struct clk *c; |
680 | 684 | ||
685 | bitmap_fill(channel_usage, NV_DMA_MAX_CHANNELS); | ||
686 | |||
681 | c = clk_get_sys("tegra-dma", NULL); | 687 | c = clk_get_sys("tegra-dma", NULL); |
682 | if (IS_ERR(c)) { | 688 | if (IS_ERR(c)) { |
683 | pr_err("Unable to get clock for APB DMA\n"); | 689 | pr_err("Unable to get clock for APB DMA\n"); |
@@ -696,18 +702,9 @@ int __init tegra_dma_init(void) | |||
696 | writel(0xFFFFFFFFul >> (31 - TEGRA_SYSTEM_DMA_CH_MAX), | 702 | writel(0xFFFFFFFFul >> (31 - TEGRA_SYSTEM_DMA_CH_MAX), |
697 | addr + APB_DMA_IRQ_MASK_SET); | 703 | addr + APB_DMA_IRQ_MASK_SET); |
698 | 704 | ||
699 | memset(channel_usage, 0, sizeof(channel_usage)); | ||
700 | memset(dma_channels, 0, sizeof(dma_channels)); | ||
701 | |||
702 | /* Reserve all the channels we are not supposed to touch */ | ||
703 | for (i = 0; i < TEGRA_SYSTEM_DMA_CH_MIN; i++) | ||
704 | __set_bit(i, channel_usage); | ||
705 | |||
706 | for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) { | 705 | for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) { |
707 | struct tegra_dma_channel *ch = &dma_channels[i]; | 706 | struct tegra_dma_channel *ch = &dma_channels[i]; |
708 | 707 | ||
709 | __clear_bit(i, channel_usage); | ||
710 | |||
711 | ch->id = i; | 708 | ch->id = i; |
712 | snprintf(ch->name, TEGRA_DMA_NAME_SIZE, "dma_channel_%d", i); | 709 | snprintf(ch->name, TEGRA_DMA_NAME_SIZE, "dma_channel_%d", i); |
713 | 710 | ||
@@ -726,14 +723,15 @@ int __init tegra_dma_init(void) | |||
726 | goto fail; | 723 | goto fail; |
727 | } | 724 | } |
728 | ch->irq = irq; | 725 | ch->irq = irq; |
726 | |||
727 | __clear_bit(i, channel_usage); | ||
729 | } | 728 | } |
730 | /* mark the shared channel allocated */ | 729 | /* mark the shared channel allocated */ |
731 | __set_bit(TEGRA_SYSTEM_DMA_CH_MIN, channel_usage); | 730 | __set_bit(TEGRA_SYSTEM_DMA_CH_MIN, channel_usage); |
732 | 731 | ||
733 | for (i = TEGRA_SYSTEM_DMA_CH_MAX+1; i < NV_DMA_MAX_CHANNELS; i++) | 732 | tegra_dma_initialized = true; |
734 | __set_bit(i, channel_usage); | ||
735 | 733 | ||
736 | return ret; | 734 | return 0; |
737 | fail: | 735 | fail: |
738 | writel(0, addr + APB_DMA_GEN); | 736 | writel(0, addr + APB_DMA_GEN); |
739 | for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) { | 737 | for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) { |