diff options
author | Tony Lindgren <tony@atomide.com> | 2008-07-03 05:24:31 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2008-07-03 05:24:31 -0400 |
commit | 4d96372e6daae89166fed7883ee092dc8db80b21 (patch) | |
tree | 56814f4e3909e1337b4c8014c1989f9345ed1ba9 /arch/arm/plat-omap | |
parent | 4a79acdc784c315d9c436ba2315d08f8f53b8adf (diff) |
ARM: OMAP: DMA: Make channels dynamic for multi-boot
Make DMA channels dynamic for multi-boot
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r-- | arch/arm/plat-omap/dma.c | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 39c637b0ffea..02f00a98783f 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c | |||
@@ -72,7 +72,6 @@ struct omap_dma_lch { | |||
72 | long flags; | 72 | long flags; |
73 | }; | 73 | }; |
74 | 74 | ||
75 | #ifndef CONFIG_ARCH_OMAP1 | ||
76 | struct dma_link_info { | 75 | struct dma_link_info { |
77 | int *linked_dmach_q; | 76 | int *linked_dmach_q; |
78 | int no_of_lchs_linked; | 77 | int no_of_lchs_linked; |
@@ -86,7 +85,9 @@ struct dma_link_info { | |||
86 | 85 | ||
87 | }; | 86 | }; |
88 | 87 | ||
89 | static struct dma_link_info dma_linked_lch[OMAP_LOGICAL_DMA_CH_COUNT]; | 88 | static struct dma_link_info *dma_linked_lch; |
89 | |||
90 | #ifndef CONFIG_ARCH_OMAP1 | ||
90 | 91 | ||
91 | /* Chain handling macros */ | 92 | /* Chain handling macros */ |
92 | #define OMAP_DMA_CHAIN_QINIT(chain_id) \ | 93 | #define OMAP_DMA_CHAIN_QINIT(chain_id) \ |
@@ -119,12 +120,14 @@ static struct dma_link_info dma_linked_lch[OMAP_LOGICAL_DMA_CH_COUNT]; | |||
119 | dma_linked_lch[chain_id].q_count++; \ | 120 | dma_linked_lch[chain_id].q_count++; \ |
120 | } while (0) | 121 | } while (0) |
121 | #endif | 122 | #endif |
123 | |||
124 | static int dma_lch_count; | ||
122 | static int dma_chan_count; | 125 | static int dma_chan_count; |
123 | 126 | ||
124 | static spinlock_t dma_chan_lock; | 127 | static spinlock_t dma_chan_lock; |
125 | static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT]; | 128 | static struct omap_dma_lch *dma_chan; |
126 | 129 | ||
127 | static const u8 omap1_dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = { | 130 | static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = { |
128 | INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3, | 131 | INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3, |
129 | INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7, | 132 | INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7, |
130 | INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10, | 133 | INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10, |
@@ -727,7 +730,7 @@ omap_dma_set_prio_lch(int lch, unsigned char read_prio, | |||
727 | { | 730 | { |
728 | u32 w; | 731 | u32 w; |
729 | 732 | ||
730 | if (unlikely((lch < 0 || lch >= OMAP_LOGICAL_DMA_CH_COUNT))) { | 733 | if (unlikely((lch < 0 || lch >= dma_lch_count))) { |
731 | printk(KERN_ERR "Invalid channel id\n"); | 734 | printk(KERN_ERR "Invalid channel id\n"); |
732 | return -EINVAL; | 735 | return -EINVAL; |
733 | } | 736 | } |
@@ -775,7 +778,7 @@ void omap_start_dma(int lch) | |||
775 | { | 778 | { |
776 | if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { | 779 | if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { |
777 | int next_lch, cur_lch; | 780 | int next_lch, cur_lch; |
778 | char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; | 781 | char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT]; |
779 | 782 | ||
780 | dma_chan_link_map[lch] = 1; | 783 | dma_chan_link_map[lch] = 1; |
781 | /* Set the link register of the first channel */ | 784 | /* Set the link register of the first channel */ |
@@ -819,7 +822,7 @@ void omap_stop_dma(int lch) | |||
819 | { | 822 | { |
820 | if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { | 823 | if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { |
821 | int next_lch, cur_lch = lch; | 824 | int next_lch, cur_lch = lch; |
822 | char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; | 825 | char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT]; |
823 | 826 | ||
824 | memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map)); | 827 | memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map)); |
825 | do { | 828 | do { |
@@ -1061,7 +1064,7 @@ int omap_request_dma_chain(int dev_id, const char *dev_name, | |||
1061 | } | 1064 | } |
1062 | 1065 | ||
1063 | if (unlikely((no_of_chans < 1 | 1066 | if (unlikely((no_of_chans < 1 |
1064 | || no_of_chans > OMAP_LOGICAL_DMA_CH_COUNT))) { | 1067 | || no_of_chans > dma_lch_count))) { |
1065 | printk(KERN_ERR "Invalid Number of channels requested\n"); | 1068 | printk(KERN_ERR "Invalid Number of channels requested\n"); |
1066 | return -EINVAL; | 1069 | return -EINVAL; |
1067 | } | 1070 | } |
@@ -1138,7 +1141,7 @@ int omap_modify_dma_chain_params(int chain_id, | |||
1138 | 1141 | ||
1139 | /* Check for input params */ | 1142 | /* Check for input params */ |
1140 | if (unlikely((chain_id < 0 | 1143 | if (unlikely((chain_id < 0 |
1141 | || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { | 1144 | || chain_id >= dma_lch_count))) { |
1142 | printk(KERN_ERR "Invalid chain id\n"); | 1145 | printk(KERN_ERR "Invalid chain id\n"); |
1143 | return -EINVAL; | 1146 | return -EINVAL; |
1144 | } | 1147 | } |
@@ -1176,7 +1179,7 @@ int omap_free_dma_chain(int chain_id) | |||
1176 | u32 i; | 1179 | u32 i; |
1177 | 1180 | ||
1178 | /* Check for input params */ | 1181 | /* Check for input params */ |
1179 | if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { | 1182 | if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { |
1180 | printk(KERN_ERR "Invalid chain id\n"); | 1183 | printk(KERN_ERR "Invalid chain id\n"); |
1181 | return -EINVAL; | 1184 | return -EINVAL; |
1182 | } | 1185 | } |
@@ -1216,7 +1219,7 @@ EXPORT_SYMBOL(omap_free_dma_chain); | |||
1216 | int omap_dma_chain_status(int chain_id) | 1219 | int omap_dma_chain_status(int chain_id) |
1217 | { | 1220 | { |
1218 | /* Check for input params */ | 1221 | /* Check for input params */ |
1219 | if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { | 1222 | if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { |
1220 | printk(KERN_ERR "Invalid chain id\n"); | 1223 | printk(KERN_ERR "Invalid chain id\n"); |
1221 | return -EINVAL; | 1224 | return -EINVAL; |
1222 | } | 1225 | } |
@@ -1265,7 +1268,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, | |||
1265 | 1268 | ||
1266 | /* Check for input params */ | 1269 | /* Check for input params */ |
1267 | if (unlikely((chain_id < 0 | 1270 | if (unlikely((chain_id < 0 |
1268 | || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { | 1271 | || chain_id >= dma_lch_count))) { |
1269 | printk(KERN_ERR "Invalid chain id\n"); | 1272 | printk(KERN_ERR "Invalid chain id\n"); |
1270 | return -EINVAL; | 1273 | return -EINVAL; |
1271 | } | 1274 | } |
@@ -1382,7 +1385,7 @@ int omap_start_dma_chain_transfers(int chain_id) | |||
1382 | int *channels; | 1385 | int *channels; |
1383 | u32 w, i; | 1386 | u32 w, i; |
1384 | 1387 | ||
1385 | if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { | 1388 | if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { |
1386 | printk(KERN_ERR "Invalid chain id\n"); | 1389 | printk(KERN_ERR "Invalid chain id\n"); |
1387 | return -EINVAL; | 1390 | return -EINVAL; |
1388 | } | 1391 | } |
@@ -1435,7 +1438,7 @@ int omap_stop_dma_chain_transfers(int chain_id) | |||
1435 | u32 sys_cf; | 1438 | u32 sys_cf; |
1436 | 1439 | ||
1437 | /* Check for input params */ | 1440 | /* Check for input params */ |
1438 | if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { | 1441 | if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { |
1439 | printk(KERN_ERR "Invalid chain id\n"); | 1442 | printk(KERN_ERR "Invalid chain id\n"); |
1440 | return -EINVAL; | 1443 | return -EINVAL; |
1441 | } | 1444 | } |
@@ -1497,7 +1500,7 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi) | |||
1497 | int *channels; | 1500 | int *channels; |
1498 | 1501 | ||
1499 | /* Check for input params */ | 1502 | /* Check for input params */ |
1500 | if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { | 1503 | if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { |
1501 | printk(KERN_ERR "Invalid chain id\n"); | 1504 | printk(KERN_ERR "Invalid chain id\n"); |
1502 | return -EINVAL; | 1505 | return -EINVAL; |
1503 | } | 1506 | } |
@@ -1537,7 +1540,7 @@ int omap_get_dma_chain_dst_pos(int chain_id) | |||
1537 | int *channels; | 1540 | int *channels; |
1538 | 1541 | ||
1539 | /* Check for input params */ | 1542 | /* Check for input params */ |
1540 | if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { | 1543 | if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { |
1541 | printk(KERN_ERR "Invalid chain id\n"); | 1544 | printk(KERN_ERR "Invalid chain id\n"); |
1542 | return -EINVAL; | 1545 | return -EINVAL; |
1543 | } | 1546 | } |
@@ -1571,7 +1574,7 @@ int omap_get_dma_chain_src_pos(int chain_id) | |||
1571 | int *channels; | 1574 | int *channels; |
1572 | 1575 | ||
1573 | /* Check for input params */ | 1576 | /* Check for input params */ |
1574 | if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { | 1577 | if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { |
1575 | printk(KERN_ERR "Invalid chain id\n"); | 1578 | printk(KERN_ERR "Invalid chain id\n"); |
1576 | return -EINVAL; | 1579 | return -EINVAL; |
1577 | } | 1580 | } |
@@ -1724,7 +1727,7 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id) | |||
1724 | printk(KERN_WARNING "Spurious DMA IRQ\n"); | 1727 | printk(KERN_WARNING "Spurious DMA IRQ\n"); |
1725 | return IRQ_HANDLED; | 1728 | return IRQ_HANDLED; |
1726 | } | 1729 | } |
1727 | for (i = 0; i < OMAP_LOGICAL_DMA_CH_COUNT && val != 0; i++) { | 1730 | for (i = 0; i < dma_lch_count && val != 0; i++) { |
1728 | if (val & 1) | 1731 | if (val & 1) |
1729 | omap2_dma_handle_ch(i); | 1732 | omap2_dma_handle_ch(i); |
1730 | val >>= 1; | 1733 | val >>= 1; |
@@ -2106,6 +2109,25 @@ static int __init omap_init_dma(void) | |||
2106 | { | 2109 | { |
2107 | int ch, r; | 2110 | int ch, r; |
2108 | 2111 | ||
2112 | if (cpu_class_is_omap1()) | ||
2113 | dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT; | ||
2114 | else | ||
2115 | dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; | ||
2116 | |||
2117 | dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count, | ||
2118 | GFP_KERNEL); | ||
2119 | if (!dma_chan) | ||
2120 | return -ENOMEM; | ||
2121 | |||
2122 | if (cpu_class_is_omap2()) { | ||
2123 | dma_linked_lch = kzalloc(sizeof(struct dma_link_info) * | ||
2124 | dma_lch_count, GFP_KERNEL); | ||
2125 | if (!dma_linked_lch) { | ||
2126 | kfree(dma_chan); | ||
2127 | return -ENOMEM; | ||
2128 | } | ||
2129 | } | ||
2130 | |||
2109 | if (cpu_is_omap15xx()) { | 2131 | if (cpu_is_omap15xx()) { |
2110 | printk(KERN_INFO "DMA support for OMAP15xx initialized\n"); | 2132 | printk(KERN_INFO "DMA support for OMAP15xx initialized\n"); |
2111 | dma_chan_count = 9; | 2133 | dma_chan_count = 9; |
@@ -2142,16 +2164,14 @@ static int __init omap_init_dma(void) | |||
2142 | u8 revision = omap_readb(OMAP_DMA4_REVISION); | 2164 | u8 revision = omap_readb(OMAP_DMA4_REVISION); |
2143 | printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", | 2165 | printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", |
2144 | revision >> 4, revision & 0xf); | 2166 | revision >> 4, revision & 0xf); |
2145 | dma_chan_count = OMAP_LOGICAL_DMA_CH_COUNT; | 2167 | dma_chan_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; |
2146 | } else { | 2168 | } else { |
2147 | dma_chan_count = 0; | 2169 | dma_chan_count = 0; |
2148 | return 0; | 2170 | return 0; |
2149 | } | 2171 | } |
2150 | 2172 | ||
2151 | memset(&lcd_dma, 0, sizeof(lcd_dma)); | ||
2152 | spin_lock_init(&lcd_dma.lock); | 2173 | spin_lock_init(&lcd_dma.lock); |
2153 | spin_lock_init(&dma_chan_lock); | 2174 | spin_lock_init(&dma_chan_lock); |
2154 | memset(&dma_chan, 0, sizeof(dma_chan)); | ||
2155 | 2175 | ||
2156 | for (ch = 0; ch < dma_chan_count; ch++) { | 2176 | for (ch = 0; ch < dma_chan_count; ch++) { |
2157 | omap_clear_dma(ch); | 2177 | omap_clear_dma(ch); |