0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <linux/module.h>
0025 #include <linux/init.h>
0026 #include <linux/sched.h>
0027 #include <linux/spinlock.h>
0028 #include <linux/errno.h>
0029 #include <linux/interrupt.h>
0030 #include <linux/irq.h>
0031 #include <linux/io.h>
0032 #include <linux/slab.h>
0033 #include <linux/delay.h>
0034
0035 #include <linux/omap-dma.h>
0036
0037 #include <linux/soc/ti/omap1-io.h>
0038 #include <linux/soc/ti/omap1-soc.h>
0039
0040 #include "tc.h"
0041
0042
0043
0044
0045
0046
0047
0048
0049 #define MAX_LOGICAL_DMA_CH_COUNT 32
0050
0051 #undef DEBUG
0052
0053 #define OMAP_DMA_ACTIVE 0x01
0054
0055 #define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
0056
0057 static struct omap_system_dma_plat_info *p;
0058 static struct omap_dma_dev_attr *d;
0059 static int enable_1510_mode;
0060 static u32 errata;
0061
0062 struct dma_link_info {
0063 int *linked_dmach_q;
0064 int no_of_lchs_linked;
0065
0066 int q_count;
0067 int q_tail;
0068 int q_head;
0069
0070 int chain_state;
0071 int chain_mode;
0072
0073 };
0074
0075 static int dma_lch_count;
0076 static int dma_chan_count;
0077 static int omap_dma_reserve_channels;
0078
0079 static DEFINE_SPINLOCK(dma_chan_lock);
0080 static struct omap_dma_lch *dma_chan;
0081
0082 static inline void omap_disable_channel_irq(int lch)
0083 {
0084
0085 p->dma_write(0, CICR, lch);
0086
0087 p->dma_read(CSR, lch);
0088 }
0089
0090 static inline void set_gdma_dev(int req, int dev)
0091 {
0092 u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
0093 int shift = ((req - 1) % 5) * 6;
0094 u32 l;
0095
0096 l = omap_readl(reg);
0097 l &= ~(0x3f << shift);
0098 l |= (dev - 1) << shift;
0099 omap_writel(l, reg);
0100 }
0101
0102 #if IS_ENABLED(CONFIG_FB_OMAP)
0103 void omap_set_dma_priority(int lch, int dst_port, int priority)
0104 {
0105 unsigned long reg;
0106 u32 l;
0107
0108 if (dma_omap1()) {
0109 switch (dst_port) {
0110 case OMAP_DMA_PORT_OCP_T1:
0111 reg = OMAP_TC_OCPT1_PRIOR;
0112 break;
0113 case OMAP_DMA_PORT_OCP_T2:
0114 reg = OMAP_TC_OCPT2_PRIOR;
0115 break;
0116 case OMAP_DMA_PORT_EMIFF:
0117 reg = OMAP_TC_EMIFF_PRIOR;
0118 break;
0119 case OMAP_DMA_PORT_EMIFS:
0120 reg = OMAP_TC_EMIFS_PRIOR;
0121 break;
0122 default:
0123 BUG();
0124 return;
0125 }
0126 l = omap_readl(reg);
0127 l &= ~(0xf << 8);
0128 l |= (priority & 0xf) << 8;
0129 omap_writel(l, reg);
0130 }
0131 }
0132 EXPORT_SYMBOL(omap_set_dma_priority);
0133 #endif
0134
0135 #if IS_ENABLED(CONFIG_USB_OMAP)
0136 #ifdef CONFIG_ARCH_OMAP15XX
0137
0138 static int omap_dma_in_1510_mode(void)
0139 {
0140 return enable_1510_mode;
0141 }
0142 #else
0143 #define omap_dma_in_1510_mode() 0
0144 #endif
0145
0146 void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
0147 int frame_count, int sync_mode,
0148 int dma_trigger, int src_or_dst_synch)
0149 {
0150 u32 l;
0151 u16 ccr;
0152
0153 l = p->dma_read(CSDP, lch);
0154 l &= ~0x03;
0155 l |= data_type;
0156 p->dma_write(l, CSDP, lch);
0157
0158 ccr = p->dma_read(CCR, lch);
0159 ccr &= ~(1 << 5);
0160 if (sync_mode == OMAP_DMA_SYNC_FRAME)
0161 ccr |= 1 << 5;
0162 p->dma_write(ccr, CCR, lch);
0163
0164 ccr = p->dma_read(CCR2, lch);
0165 ccr &= ~(1 << 2);
0166 if (sync_mode == OMAP_DMA_SYNC_BLOCK)
0167 ccr |= 1 << 2;
0168 p->dma_write(ccr, CCR2, lch);
0169 p->dma_write(elem_count, CEN, lch);
0170 p->dma_write(frame_count, CFN, lch);
0171 }
0172 EXPORT_SYMBOL(omap_set_dma_transfer_params);
0173
0174 void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode)
0175 {
0176 if (!dma_omap15xx()) {
0177 u32 l;
0178
0179 l = p->dma_read(LCH_CTRL, lch);
0180 l &= ~0x7;
0181 l |= mode;
0182 p->dma_write(l, LCH_CTRL, lch);
0183 }
0184 }
0185 EXPORT_SYMBOL(omap_set_dma_channel_mode);
0186
0187
0188 void omap_set_dma_src_params(int lch, int src_port, int src_amode,
0189 unsigned long src_start,
0190 int src_ei, int src_fi)
0191 {
0192 u32 l;
0193 u16 w;
0194
0195 w = p->dma_read(CSDP, lch);
0196 w &= ~(0x1f << 2);
0197 w |= src_port << 2;
0198 p->dma_write(w, CSDP, lch);
0199
0200 l = p->dma_read(CCR, lch);
0201 l &= ~(0x03 << 12);
0202 l |= src_amode << 12;
0203 p->dma_write(l, CCR, lch);
0204
0205 p->dma_write(src_start, CSSA, lch);
0206
0207 p->dma_write(src_ei, CSEI, lch);
0208 p->dma_write(src_fi, CSFI, lch);
0209 }
0210 EXPORT_SYMBOL(omap_set_dma_src_params);
0211
0212 void omap_set_dma_src_data_pack(int lch, int enable)
0213 {
0214 u32 l;
0215
0216 l = p->dma_read(CSDP, lch);
0217 l &= ~(1 << 6);
0218 if (enable)
0219 l |= (1 << 6);
0220 p->dma_write(l, CSDP, lch);
0221 }
0222 EXPORT_SYMBOL(omap_set_dma_src_data_pack);
0223
0224 void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
0225 {
0226 unsigned int burst = 0;
0227 u32 l;
0228
0229 l = p->dma_read(CSDP, lch);
0230 l &= ~(0x03 << 7);
0231
0232 switch (burst_mode) {
0233 case OMAP_DMA_DATA_BURST_DIS:
0234 break;
0235 case OMAP_DMA_DATA_BURST_4:
0236 burst = 0x2;
0237 break;
0238 case OMAP_DMA_DATA_BURST_8:
0239
0240
0241
0242
0243 fallthrough;
0244 case OMAP_DMA_DATA_BURST_16:
0245
0246 fallthrough;
0247 default:
0248 BUG();
0249 }
0250
0251 l |= (burst << 7);
0252 p->dma_write(l, CSDP, lch);
0253 }
0254 EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
0255
0256
0257 void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
0258 unsigned long dest_start,
0259 int dst_ei, int dst_fi)
0260 {
0261 u32 l;
0262
0263 l = p->dma_read(CSDP, lch);
0264 l &= ~(0x1f << 9);
0265 l |= dest_port << 9;
0266 p->dma_write(l, CSDP, lch);
0267
0268 l = p->dma_read(CCR, lch);
0269 l &= ~(0x03 << 14);
0270 l |= dest_amode << 14;
0271 p->dma_write(l, CCR, lch);
0272
0273 p->dma_write(dest_start, CDSA, lch);
0274
0275 p->dma_write(dst_ei, CDEI, lch);
0276 p->dma_write(dst_fi, CDFI, lch);
0277 }
0278 EXPORT_SYMBOL(omap_set_dma_dest_params);
0279
0280 void omap_set_dma_dest_data_pack(int lch, int enable)
0281 {
0282 u32 l;
0283
0284 l = p->dma_read(CSDP, lch);
0285 l &= ~(1 << 13);
0286 if (enable)
0287 l |= 1 << 13;
0288 p->dma_write(l, CSDP, lch);
0289 }
0290 EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
0291
0292 void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
0293 {
0294 unsigned int burst = 0;
0295 u32 l;
0296
0297 l = p->dma_read(CSDP, lch);
0298 l &= ~(0x03 << 14);
0299
0300 switch (burst_mode) {
0301 case OMAP_DMA_DATA_BURST_DIS:
0302 break;
0303 case OMAP_DMA_DATA_BURST_4:
0304 burst = 0x2;
0305 break;
0306 case OMAP_DMA_DATA_BURST_8:
0307 burst = 0x3;
0308 break;
0309 case OMAP_DMA_DATA_BURST_16:
0310
0311 fallthrough;
0312 default:
0313 printk(KERN_ERR "Invalid DMA burst mode\n");
0314 BUG();
0315 return;
0316 }
0317 l |= (burst << 14);
0318 p->dma_write(l, CSDP, lch);
0319 }
0320 EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
0321
0322 static inline void omap_enable_channel_irq(int lch)
0323 {
0324
0325 p->dma_read(CSR, lch);
0326
0327
0328 p->dma_write(dma_chan[lch].enabled_irqs, CICR, lch);
0329 }
0330
0331 void omap_disable_dma_irq(int lch, u16 bits)
0332 {
0333 dma_chan[lch].enabled_irqs &= ~bits;
0334 }
0335 EXPORT_SYMBOL(omap_disable_dma_irq);
0336
0337 static inline void enable_lnk(int lch)
0338 {
0339 u32 l;
0340
0341 l = p->dma_read(CLNK_CTRL, lch);
0342
0343 l &= ~(1 << 14);
0344
0345
0346 if (dma_chan[lch].next_lch != -1)
0347 l = dma_chan[lch].next_lch | (1 << 15);
0348
0349 p->dma_write(l, CLNK_CTRL, lch);
0350 }
0351
0352 static inline void disable_lnk(int lch)
0353 {
0354 u32 l;
0355
0356 l = p->dma_read(CLNK_CTRL, lch);
0357
0358
0359 omap_disable_channel_irq(lch);
0360
0361
0362 l |= 1 << 14;
0363
0364 p->dma_write(l, CLNK_CTRL, lch);
0365 dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
0366 }
0367 #endif
0368
0369 int omap_request_dma(int dev_id, const char *dev_name,
0370 void (*callback)(int lch, u16 ch_status, void *data),
0371 void *data, int *dma_ch_out)
0372 {
0373 int ch, free_ch = -1;
0374 unsigned long flags;
0375 struct omap_dma_lch *chan;
0376
0377 WARN(strcmp(dev_name, "DMA engine"), "Using deprecated platform DMA API - please update to DMA engine");
0378
0379 spin_lock_irqsave(&dma_chan_lock, flags);
0380 for (ch = 0; ch < dma_chan_count; ch++) {
0381 if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
0382 free_ch = ch;
0383
0384 break;
0385 }
0386 }
0387 if (free_ch == -1) {
0388 spin_unlock_irqrestore(&dma_chan_lock, flags);
0389 return -EBUSY;
0390 }
0391 chan = dma_chan + free_ch;
0392 chan->dev_id = dev_id;
0393
0394 if (p->clear_lch_regs)
0395 p->clear_lch_regs(free_ch);
0396
0397 spin_unlock_irqrestore(&dma_chan_lock, flags);
0398
0399 chan->dev_name = dev_name;
0400 chan->callback = callback;
0401 chan->data = data;
0402 chan->flags = 0;
0403
0404 chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
0405
0406 chan->enabled_irqs |= OMAP1_DMA_TOUT_IRQ;
0407
0408 if (dma_omap16xx()) {
0409
0410 if (dev_id != 0) {
0411 set_gdma_dev(free_ch + 1, dev_id);
0412 dev_id = free_ch + 1;
0413 }
0414
0415
0416
0417
0418 p->dma_write(dev_id | (1 << 10), CCR, free_ch);
0419 } else {
0420 p->dma_write(dev_id, CCR, free_ch);
0421 }
0422
0423 *dma_ch_out = free_ch;
0424
0425 return 0;
0426 }
0427 EXPORT_SYMBOL(omap_request_dma);
0428
0429 void omap_free_dma(int lch)
0430 {
0431 unsigned long flags;
0432
0433 if (dma_chan[lch].dev_id == -1) {
0434 pr_err("omap_dma: trying to free unallocated DMA channel %d\n",
0435 lch);
0436 return;
0437 }
0438
0439
0440 omap_disable_channel_irq(lch);
0441
0442
0443 p->dma_write(0, CCR, lch);
0444
0445 spin_lock_irqsave(&dma_chan_lock, flags);
0446 dma_chan[lch].dev_id = -1;
0447 dma_chan[lch].next_lch = -1;
0448 dma_chan[lch].callback = NULL;
0449 spin_unlock_irqrestore(&dma_chan_lock, flags);
0450 }
0451 EXPORT_SYMBOL(omap_free_dma);
0452
0453
0454
0455
0456
0457 static void omap_clear_dma(int lch)
0458 {
0459 unsigned long flags;
0460
0461 local_irq_save(flags);
0462 p->clear_dma(lch);
0463 local_irq_restore(flags);
0464 }
0465
0466 #if IS_ENABLED(CONFIG_USB_OMAP)
0467 void omap_start_dma(int lch)
0468 {
0469 u32 l;
0470
0471
0472
0473
0474
0475 if (dma_omap15xx())
0476 p->dma_write(0, CPC, lch);
0477 else
0478 p->dma_write(0, CDAC, lch);
0479
0480 if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
0481 int next_lch, cur_lch;
0482 char dma_chan_link_map[MAX_LOGICAL_DMA_CH_COUNT];
0483
0484
0485 enable_lnk(lch);
0486
0487 memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
0488 dma_chan_link_map[lch] = 1;
0489
0490 cur_lch = dma_chan[lch].next_lch;
0491 do {
0492 next_lch = dma_chan[cur_lch].next_lch;
0493
0494
0495 if (dma_chan_link_map[cur_lch])
0496 break;
0497
0498 dma_chan_link_map[cur_lch] = 1;
0499
0500 enable_lnk(cur_lch);
0501 omap_enable_channel_irq(cur_lch);
0502
0503 cur_lch = next_lch;
0504 } while (next_lch != -1);
0505 } else if (IS_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS))
0506 p->dma_write(lch, CLNK_CTRL, lch);
0507
0508 omap_enable_channel_irq(lch);
0509
0510 l = p->dma_read(CCR, lch);
0511
0512 if (IS_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING))
0513 l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
0514 l |= OMAP_DMA_CCR_EN;
0515
0516
0517
0518
0519
0520
0521
0522 mb();
0523 p->dma_write(l, CCR, lch);
0524
0525 dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
0526 }
0527 EXPORT_SYMBOL(omap_start_dma);
0528
0529 void omap_stop_dma(int lch)
0530 {
0531 u32 l;
0532
0533
0534 omap_disable_channel_irq(lch);
0535
0536 l = p->dma_read(CCR, lch);
0537 if (IS_DMA_ERRATA(DMA_ERRATA_i541) &&
0538 (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
0539 int i = 0;
0540 u32 sys_cf;
0541
0542
0543 l = p->dma_read(OCP_SYSCONFIG, lch);
0544 sys_cf = l;
0545 l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
0546 l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
0547 p->dma_write(l , OCP_SYSCONFIG, 0);
0548
0549 l = p->dma_read(CCR, lch);
0550 l &= ~OMAP_DMA_CCR_EN;
0551 p->dma_write(l, CCR, lch);
0552
0553
0554 l = p->dma_read(CCR, lch);
0555 while (i < 100 && (l & (OMAP_DMA_CCR_RD_ACTIVE |
0556 OMAP_DMA_CCR_WR_ACTIVE))) {
0557 udelay(5);
0558 i++;
0559 l = p->dma_read(CCR, lch);
0560 }
0561 if (i >= 100)
0562 pr_err("DMA drain did not complete on lch %d\n", lch);
0563
0564 p->dma_write(sys_cf, OCP_SYSCONFIG, lch);
0565 } else {
0566 l &= ~OMAP_DMA_CCR_EN;
0567 p->dma_write(l, CCR, lch);
0568 }
0569
0570
0571
0572
0573
0574
0575 mb();
0576
0577 if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
0578 int next_lch, cur_lch = lch;
0579 char dma_chan_link_map[MAX_LOGICAL_DMA_CH_COUNT];
0580
0581 memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
0582 do {
0583
0584 if (dma_chan_link_map[cur_lch])
0585 break;
0586
0587 dma_chan_link_map[cur_lch] = 1;
0588
0589 disable_lnk(cur_lch);
0590
0591 next_lch = dma_chan[cur_lch].next_lch;
0592 cur_lch = next_lch;
0593 } while (next_lch != -1);
0594 }
0595
0596 dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
0597 }
0598 EXPORT_SYMBOL(omap_stop_dma);
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612 dma_addr_t omap_get_dma_src_pos(int lch)
0613 {
0614 dma_addr_t offset = 0;
0615
0616 if (dma_omap15xx())
0617 offset = p->dma_read(CPC, lch);
0618 else
0619 offset = p->dma_read(CSAC, lch);
0620
0621 if (IS_DMA_ERRATA(DMA_ERRATA_3_3) && offset == 0)
0622 offset = p->dma_read(CSAC, lch);
0623
0624 if (!dma_omap15xx()) {
0625
0626
0627
0628
0629
0630 if (likely(p->dma_read(CDAC, lch)))
0631 offset = p->dma_read(CSAC, lch);
0632 else
0633 offset = p->dma_read(CSSA, lch);
0634 }
0635
0636 offset |= (p->dma_read(CSSA, lch) & 0xFFFF0000);
0637
0638 return offset;
0639 }
0640 EXPORT_SYMBOL(omap_get_dma_src_pos);
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650 dma_addr_t omap_get_dma_dst_pos(int lch)
0651 {
0652 dma_addr_t offset = 0;
0653
0654 if (dma_omap15xx())
0655 offset = p->dma_read(CPC, lch);
0656 else
0657 offset = p->dma_read(CDAC, lch);
0658
0659
0660
0661
0662
0663 if (!dma_omap15xx() && offset == 0) {
0664 offset = p->dma_read(CDAC, lch);
0665
0666
0667
0668
0669
0670 if (unlikely(!offset))
0671 offset = p->dma_read(CDSA, lch);
0672 }
0673
0674 offset |= (p->dma_read(CDSA, lch) & 0xFFFF0000);
0675
0676 return offset;
0677 }
0678 EXPORT_SYMBOL(omap_get_dma_dst_pos);
0679
0680 int omap_get_dma_active_status(int lch)
0681 {
0682 return (p->dma_read(CCR, lch) & OMAP_DMA_CCR_EN) != 0;
0683 }
0684 EXPORT_SYMBOL(omap_get_dma_active_status);
0685 #endif
0686
0687 int omap_dma_running(void)
0688 {
0689 int lch;
0690
0691 if (omap_lcd_dma_running())
0692 return 1;
0693
0694 for (lch = 0; lch < dma_chan_count; lch++)
0695 if (p->dma_read(CCR, lch) & OMAP_DMA_CCR_EN)
0696 return 1;
0697
0698 return 0;
0699 }
0700
0701
0702
0703 static int omap1_dma_handle_ch(int ch)
0704 {
0705 u32 csr;
0706
0707 if (enable_1510_mode && ch >= 6) {
0708 csr = dma_chan[ch].saved_csr;
0709 dma_chan[ch].saved_csr = 0;
0710 } else
0711 csr = p->dma_read(CSR, ch);
0712 if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
0713 dma_chan[ch + 6].saved_csr = csr >> 7;
0714 csr &= 0x7f;
0715 }
0716 if ((csr & 0x3f) == 0)
0717 return 0;
0718 if (unlikely(dma_chan[ch].dev_id == -1)) {
0719 pr_warn("Spurious interrupt from DMA channel %d (CSR %04x)\n",
0720 ch, csr);
0721 return 0;
0722 }
0723 if (unlikely(csr & OMAP1_DMA_TOUT_IRQ))
0724 pr_warn("DMA timeout with device %d\n", dma_chan[ch].dev_id);
0725 if (unlikely(csr & OMAP_DMA_DROP_IRQ))
0726 pr_warn("DMA synchronization event drop occurred with device %d\n",
0727 dma_chan[ch].dev_id);
0728 if (likely(csr & OMAP_DMA_BLOCK_IRQ))
0729 dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
0730 if (likely(dma_chan[ch].callback != NULL))
0731 dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
0732
0733 return 1;
0734 }
0735
0736 static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
0737 {
0738 int ch = ((int) dev_id) - 1;
0739 int handled = 0;
0740
0741 for (;;) {
0742 int handled_now = 0;
0743
0744 handled_now += omap1_dma_handle_ch(ch);
0745 if (enable_1510_mode && dma_chan[ch + 6].saved_csr)
0746 handled_now += omap1_dma_handle_ch(ch + 6);
0747 if (!handled_now)
0748 break;
0749 handled += handled_now;
0750 }
0751
0752 return handled ? IRQ_HANDLED : IRQ_NONE;
0753 }
0754
0755 struct omap_system_dma_plat_info *omap_get_plat_info(void)
0756 {
0757 return p;
0758 }
0759 EXPORT_SYMBOL_GPL(omap_get_plat_info);
0760
0761 static int omap_system_dma_probe(struct platform_device *pdev)
0762 {
0763 int ch, ret = 0;
0764 int dma_irq;
0765 char irq_name[4];
0766
0767 p = pdev->dev.platform_data;
0768 if (!p) {
0769 dev_err(&pdev->dev,
0770 "%s: System DMA initialized without platform data\n",
0771 __func__);
0772 return -EINVAL;
0773 }
0774
0775 d = p->dma_attr;
0776 errata = p->errata;
0777
0778 if ((d->dev_caps & RESERVE_CHANNEL) && omap_dma_reserve_channels
0779 && (omap_dma_reserve_channels < d->lch_count))
0780 d->lch_count = omap_dma_reserve_channels;
0781
0782 dma_lch_count = d->lch_count;
0783 dma_chan_count = dma_lch_count;
0784 enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;
0785
0786 dma_chan = devm_kcalloc(&pdev->dev, dma_lch_count,
0787 sizeof(*dma_chan), GFP_KERNEL);
0788 if (!dma_chan)
0789 return -ENOMEM;
0790
0791 for (ch = 0; ch < dma_chan_count; ch++) {
0792 omap_clear_dma(ch);
0793
0794 dma_chan[ch].dev_id = -1;
0795 dma_chan[ch].next_lch = -1;
0796
0797 if (ch >= 6 && enable_1510_mode)
0798 continue;
0799
0800
0801
0802
0803
0804 sprintf(&irq_name[0], "%d", ch);
0805 dma_irq = platform_get_irq_byname(pdev, irq_name);
0806
0807 if (dma_irq < 0) {
0808 ret = dma_irq;
0809 goto exit_dma_irq_fail;
0810 }
0811
0812
0813 if (dma_irq == INT_DMA_LCD)
0814 continue;
0815
0816 ret = request_irq(dma_irq,
0817 omap1_dma_irq_handler, 0, "DMA",
0818 (void *) (ch + 1));
0819 if (ret != 0)
0820 goto exit_dma_irq_fail;
0821 }
0822
0823
0824 if (d->dev_caps & HS_CHANNELS_RESERVED) {
0825 pr_info("Reserving DMA channels 0 and 1 for HS ROM code\n");
0826 dma_chan[0].dev_id = 0;
0827 dma_chan[1].dev_id = 1;
0828 }
0829 p->show_dma_caps();
0830 return 0;
0831
0832 exit_dma_irq_fail:
0833 return ret;
0834 }
0835
0836 static int omap_system_dma_remove(struct platform_device *pdev)
0837 {
0838 int dma_irq, irq_rel = 0;
0839
0840 for ( ; irq_rel < dma_chan_count; irq_rel++) {
0841 dma_irq = platform_get_irq(pdev, irq_rel);
0842 free_irq(dma_irq, (void *)(irq_rel + 1));
0843 }
0844
0845 return 0;
0846 }
0847
0848 static struct platform_driver omap_system_dma_driver = {
0849 .probe = omap_system_dma_probe,
0850 .remove = omap_system_dma_remove,
0851 .driver = {
0852 .name = "omap_dma_system"
0853 },
0854 };
0855
0856 static int __init omap_system_dma_init(void)
0857 {
0858 return platform_driver_register(&omap_system_dma_driver);
0859 }
0860 arch_initcall(omap_system_dma_init);
0861
0862 static void __exit omap_system_dma_exit(void)
0863 {
0864 platform_driver_unregister(&omap_system_dma_driver);
0865 }
0866
0867 MODULE_DESCRIPTION("OMAP SYSTEM DMA DRIVER");
0868 MODULE_LICENSE("GPL");
0869 MODULE_AUTHOR("Texas Instruments Inc");
0870
0871
0872
0873
0874
0875 static int __init omap_dma_cmdline_reserve_ch(char *str)
0876 {
0877 if (get_option(&str, &omap_dma_reserve_channels) != 1)
0878 omap_dma_reserve_channels = 0;
0879 return 1;
0880 }
0881
0882 __setup("omap_dma_reserve_ch=", omap_dma_cmdline_reserve_ch);
0883
0884