@@ -45,7 +45,7 @@ struct tusb_omap_dma_ch {
45
45
u8 tx ;
46
46
struct musb_hw_ep * hw_ep ;
47
47
48
- struct tusb_dma_data dma_data ;
48
+ struct tusb_dma_data * dma_data ;
49
49
50
50
struct tusb_omap_dma * tusb_dma ;
51
51
@@ -62,7 +62,7 @@ struct tusb_omap_dma {
62
62
struct dma_controller controller ;
63
63
void __iomem * tbase ;
64
64
65
- struct tusb_dma_data dma_data ;
65
+ struct tusb_dma_data dma_pool [ MAX_DMAREQ ] ;
66
66
unsigned multichannel :1 ;
67
67
};
68
68
@@ -120,10 +120,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
120
120
121
121
spin_lock_irqsave (& musb -> lock , flags );
122
122
123
- if (tusb_dma -> multichannel )
124
- ch = chdat -> dma_data .ch ;
125
- else
126
- ch = tusb_dma -> dma_data .ch ;
123
+ ch = chdat -> dma_data -> ch ;
127
124
128
125
if (ch_status != OMAP_DMA_BLOCK_IRQ )
129
126
printk (KERN_ERR "TUSB DMA error status: %i\n" , ch_status );
@@ -248,7 +245,8 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
248
245
dma_remaining = TUSB_EP_CONFIG_XFR_SIZE (dma_remaining );
249
246
if (dma_remaining ) {
250
247
dev_dbg (musb -> controller , "Busy %s dma ch%i, not using: %08x\n" ,
251
- chdat -> tx ? "tx" : "rx" , chdat -> dma_data .ch ,
248
+ chdat -> tx ? "tx" : "rx" ,
249
+ chdat -> dma_data ? chdat -> dma_data -> ch : -1 ,
252
250
dma_remaining );
253
251
return false;
254
252
}
@@ -260,11 +258,8 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
260
258
else
261
259
chdat -> transfer_packet_sz = packet_sz ;
262
260
263
- if (tusb_dma -> multichannel ) {
264
- dma_data = & chdat -> dma_data ;
265
- } else {
266
- dma_data = & tusb_dma -> dma_data ;
267
-
261
+ dma_data = chdat -> dma_data ;
262
+ if (!tusb_dma -> multichannel ) {
268
263
if (tusb_omap_use_shared_dmareq (chdat ) != 0 ) {
269
264
dev_dbg (musb -> controller , "could not get dma for ep%i\n" , chdat -> epnum );
270
265
return false;
@@ -276,10 +271,10 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
276
271
WARN_ON (1 );
277
272
return false;
278
273
}
279
-
280
- omap_set_dma_callback (dma_data -> ch , tusb_omap_dma_cb , channel );
281
274
}
282
275
276
+ omap_set_dma_callback (dma_data -> ch , tusb_omap_dma_cb , channel );
277
+
283
278
chdat -> packet_sz = packet_sz ;
284
279
chdat -> len = len ;
285
280
channel -> actual_len = 0 ;
@@ -410,19 +405,9 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
410
405
static int tusb_omap_dma_abort (struct dma_channel * channel )
411
406
{
412
407
struct tusb_omap_dma_ch * chdat = to_chdat (channel );
413
- struct tusb_omap_dma * tusb_dma = chdat -> tusb_dma ;
414
- struct tusb_dma_data * dma_data = & tusb_dma -> dma_data ;
415
408
416
- if (!tusb_dma -> multichannel ) {
417
- if (dma_data -> ch >= 0 ) {
418
- omap_stop_dma (dma_data -> ch );
419
- omap_free_dma (dma_data -> ch );
420
- dma_data -> ch = -1 ;
421
- }
422
-
423
- dma_data -> dmareq = -1 ;
424
- dma_data -> sync_dev = -1 ;
425
- }
409
+ if (chdat -> dma_data )
410
+ omap_stop_dma (chdat -> dma_data -> ch );
426
411
427
412
channel -> status = MUSB_DMA_STATUS_FREE ;
428
413
@@ -434,15 +419,6 @@ static inline int tusb_omap_dma_allocate_dmareq(struct tusb_omap_dma_ch *chdat)
434
419
u32 reg = musb_readl (chdat -> tbase , TUSB_DMA_EP_MAP );
435
420
int i , dmareq_nr = -1 ;
436
421
437
- const int sync_dev [6 ] = {
438
- OMAP24XX_DMA_EXT_DMAREQ0 ,
439
- OMAP24XX_DMA_EXT_DMAREQ1 ,
440
- OMAP242X_DMA_EXT_DMAREQ2 ,
441
- OMAP242X_DMA_EXT_DMAREQ3 ,
442
- OMAP242X_DMA_EXT_DMAREQ4 ,
443
- OMAP242X_DMA_EXT_DMAREQ5 ,
444
- };
445
-
446
422
for (i = 0 ; i < MAX_DMAREQ ; i ++ ) {
447
423
int cur = (reg & (0xf << (i * 5 ))) >> (i * 5 );
448
424
if (cur == 0 ) {
@@ -459,8 +435,7 @@ static inline int tusb_omap_dma_allocate_dmareq(struct tusb_omap_dma_ch *chdat)
459
435
reg |= ((1 << 4 ) << (dmareq_nr * 5 ));
460
436
musb_writel (chdat -> tbase , TUSB_DMA_EP_MAP , reg );
461
437
462
- chdat -> dma_data .dmareq = dmareq_nr ;
463
- chdat -> dma_data .sync_dev = sync_dev [chdat -> dma_data .dmareq ];
438
+ chdat -> dma_data = & chdat -> tusb_dma -> dma_pool [dmareq_nr ];
464
439
465
440
return 0 ;
466
441
}
@@ -469,15 +444,14 @@ static inline void tusb_omap_dma_free_dmareq(struct tusb_omap_dma_ch *chdat)
469
444
{
470
445
u32 reg ;
471
446
472
- if (!chdat || chdat -> dma_data . dmareq < 0 )
447
+ if (!chdat || ! chdat -> dma_data || chdat -> dma_data -> dmareq < 0 )
473
448
return ;
474
449
475
450
reg = musb_readl (chdat -> tbase , TUSB_DMA_EP_MAP );
476
- reg &= ~(0x1f << (chdat -> dma_data . dmareq * 5 ));
451
+ reg &= ~(0x1f << (chdat -> dma_data -> dmareq * 5 ));
477
452
musb_writel (chdat -> tbase , TUSB_DMA_EP_MAP , reg );
478
453
479
- chdat -> dma_data .dmareq = -1 ;
480
- chdat -> dma_data .sync_dev = -1 ;
454
+ chdat -> dma_data = NULL ;
481
455
}
482
456
483
457
static struct dma_channel * dma_channel_pool [MAX_DMAREQ ];
@@ -488,8 +462,6 @@ tusb_omap_dma_allocate(struct dma_controller *c,
488
462
u8 tx )
489
463
{
490
464
int ret , i ;
491
- const char * dev_name ;
492
- void * cb_data ;
493
465
struct tusb_omap_dma * tusb_dma ;
494
466
struct musb * musb ;
495
467
void __iomem * tbase ;
@@ -543,46 +515,22 @@ tusb_omap_dma_allocate(struct dma_controller *c,
543
515
channel -> desired_mode = 0 ;
544
516
channel -> actual_len = 0 ;
545
517
546
- if (tusb_dma -> multichannel ) {
547
- dma_data = & chdat -> dma_data ;
548
- ret = tusb_omap_dma_allocate_dmareq (chdat );
549
- if (ret != 0 )
550
- goto free_dmareq ;
551
-
552
- if (chdat -> tx )
553
- dev_name = "TUSB transmit" ;
554
- else
555
- dev_name = "TUSB receive" ;
556
- cb_data = channel ;
557
- } else if (tusb_dma -> dma_data .ch == -1 ) {
558
- dma_data = & tusb_dma -> dma_data ;
559
- dma_data -> dmareq = 0 ;
560
- dma_data -> sync_dev = OMAP24XX_DMA_EXT_DMAREQ0 ;
561
-
562
- dev_name = "TUSB shared" ;
563
- /* Callback data gets set later in the shared dmareq case */
564
- cb_data = NULL ;
565
-
566
- chdat -> dma_data .dmareq = -1 ;
567
- chdat -> dma_data .ch = -1 ;
568
- chdat -> dma_data .sync_dev = -1 ;
518
+ if (!chdat -> dma_data ) {
519
+ if (tusb_dma -> multichannel ) {
520
+ ret = tusb_omap_dma_allocate_dmareq (chdat );
521
+ if (ret != 0 )
522
+ goto free_dmareq ;
523
+ } else {
524
+ chdat -> dma_data = & tusb_dma -> dma_pool [0 ];
525
+ }
569
526
}
570
527
571
- if (dma_data ) {
572
- ret = omap_request_dma (dma_data -> sync_dev , dev_name ,
573
- tusb_omap_dma_cb , cb_data ,
574
- & dma_data -> ch );
575
- if (ret != 0 )
576
- goto free_dmareq ;
577
- } else {
578
- /* Already allocated shared, single DMA channel. */
579
- dma_data = & tusb_dma -> dma_data ;
580
- }
528
+ dma_data = chdat -> dma_data ;
581
529
582
530
dev_dbg (musb -> controller , "ep%i %s dma: %s dma%i dmareq%i sync%i\n" ,
583
531
chdat -> epnum ,
584
532
chdat -> tx ? "tx" : "rx" ,
585
- chdat -> dma_data . ch >= 0 ? "dedicated " : "shared " ,
533
+ tusb_dma -> multichannel ? "shared " : "dedicated " ,
586
534
dma_data -> ch , dma_data -> dmareq , dma_data -> sync_dev );
587
535
588
536
return channel ;
@@ -604,7 +552,7 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
604
552
u32 reg ;
605
553
606
554
dev_dbg (musb -> controller , "ep%i ch%i\n" , chdat -> epnum ,
607
- chdat -> dma_data . ch );
555
+ chdat -> dma_data -> ch );
608
556
609
557
reg = musb_readl (tbase , TUSB_DMA_INT_MASK );
610
558
if (chdat -> tx )
@@ -622,14 +570,8 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
622
570
623
571
channel -> status = MUSB_DMA_STATUS_UNKNOWN ;
624
572
625
- if (chdat -> dma_data .ch >= 0 ) {
626
- omap_stop_dma (chdat -> dma_data .ch );
627
- omap_free_dma (chdat -> dma_data .ch );
628
- chdat -> dma_data .ch = -1 ;
629
- }
630
-
631
- if (chdat -> dma_data .dmareq >= 0 )
632
- tusb_omap_dma_free_dmareq (chdat );
573
+ omap_stop_dma (chdat -> dma_data -> ch );
574
+ tusb_omap_dma_free_dmareq (chdat );
633
575
634
576
channel = NULL ;
635
577
}
@@ -646,15 +588,73 @@ void tusb_dma_controller_destroy(struct dma_controller *c)
646
588
kfree (ch -> private_data );
647
589
kfree (ch );
648
590
}
649
- }
650
591
651
- if (tusb_dma && !tusb_dma -> multichannel && tusb_dma -> dma_data .ch >= 0 )
652
- omap_free_dma (tusb_dma -> dma_data .ch );
592
+ /* Free up the DMA channels */
593
+ if (tusb_dma && tusb_dma -> dma_pool [i ].ch >= 0 )
594
+ omap_free_dma (tusb_dma -> dma_pool [i ].ch );
595
+ }
653
596
654
597
kfree (tusb_dma );
655
598
}
656
599
EXPORT_SYMBOL_GPL (tusb_dma_controller_destroy );
657
600
601
+ static int tusb_omap_allocate_dma_pool (struct tusb_omap_dma * tusb_dma )
602
+ {
603
+ int i ;
604
+ int ret = 0 ;
605
+ const int sync_dev [6 ] = {
606
+ OMAP24XX_DMA_EXT_DMAREQ0 ,
607
+ OMAP24XX_DMA_EXT_DMAREQ1 ,
608
+ OMAP242X_DMA_EXT_DMAREQ2 ,
609
+ OMAP242X_DMA_EXT_DMAREQ3 ,
610
+ OMAP242X_DMA_EXT_DMAREQ4 ,
611
+ OMAP242X_DMA_EXT_DMAREQ5 ,
612
+ };
613
+
614
+ for (i = 0 ; i < MAX_DMAREQ ; i ++ ) {
615
+ struct tusb_dma_data * dma_data = & tusb_dma -> dma_pool [i ];
616
+
617
+ /*
618
+ * Request DMA channels:
619
+ * - one channel in case of non multichannel mode
620
+ * - MAX_DMAREQ number of channels in multichannel mode
621
+ */
622
+ if (i == 0 || tusb_dma -> multichannel ) {
623
+ char ch_name [8 ];
624
+
625
+ sprintf (ch_name , "dmareq%d" , i );
626
+ dma_data -> sync_dev = sync_dev [i ];
627
+ dma_data -> ch = -1 ;
628
+ /* callback data is ngoing to be set later */
629
+ ret = omap_request_dma (dma_data -> sync_dev , ch_name ,
630
+ tusb_omap_dma_cb , NULL , & dma_data -> ch );
631
+ if (ret != 0 ) {
632
+ dev_err (tusb_dma -> controller .musb -> controller ,
633
+ "Failed to request %s\n" , ch_name );
634
+ goto dma_error ;
635
+ }
636
+
637
+ dma_data -> dmareq = i ;
638
+ } else {
639
+ dma_data -> dmareq = -1 ;
640
+ dma_data -> sync_dev = -1 ;
641
+ dma_data -> ch = -1 ;
642
+ }
643
+ }
644
+
645
+ return 0 ;
646
+
647
+ dma_error :
648
+ for (; i >= 0 ; i -- ) {
649
+ struct tusb_dma_data * dma_data = & tusb_dma -> dma_pool [i ];
650
+
651
+ if (dma_data -> ch >= 0 )
652
+ omap_free_dma (dma_data -> ch );
653
+ }
654
+
655
+ return ret ;
656
+ }
657
+
658
658
struct dma_controller *
659
659
tusb_dma_controller_create (struct musb * musb , void __iomem * base )
660
660
{
@@ -679,10 +679,6 @@ tusb_dma_controller_create(struct musb *musb, void __iomem *base)
679
679
tusb_dma -> controller .musb = musb ;
680
680
tusb_dma -> tbase = musb -> ctrl_base ;
681
681
682
- tusb_dma -> dma_data .ch = -1 ;
683
- tusb_dma -> dma_data .dmareq = -1 ;
684
- tusb_dma -> dma_data .sync_dev = -1 ;
685
-
686
682
tusb_dma -> controller .channel_alloc = tusb_omap_dma_allocate ;
687
683
tusb_dma -> controller .channel_release = tusb_omap_dma_release ;
688
684
tusb_dma -> controller .channel_program = tusb_omap_dma_program ;
@@ -709,6 +705,9 @@ tusb_dma_controller_create(struct musb *musb, void __iomem *base)
709
705
ch -> private_data = chdat ;
710
706
}
711
707
708
+ if (tusb_omap_allocate_dma_pool (tusb_dma ))
709
+ goto cleanup ;
710
+
712
711
return & tusb_dma -> controller ;
713
712
714
713
cleanup :
0 commit comments