#include "musb_core.h"
 
-/*
- * REVISIT: With TUSB2.0 only one dmareq line can be used at a time.
- * This should get fixed in hardware at some point.
- */
-#define BROKEN_DMAREQ
-
-#ifdef BROKEN_DMAREQ
-#define dmareq_works()         0
-#else
-#define dmareq_works()         1
-#endif
-
 #define to_chdat(c)            (struct tusb_omap_dma_ch *)(c)->private_data
 
 #define MAX_DMAREQ             5       /* REVISIT: Really 6, but req5 not OK */
        int                             ch;
        s8                              dmareq;
        s8                              sync_dev;
+       unsigned                        multichannel:1;
 };
 
 static int tusb_omap_dma_start(struct dma_controller *c)
        return 0;
 }
 
-#ifdef BROKEN_DMAREQ
-
 /*
  * Allocate dmareq0 to the current channel unless it's already taken
  */
        musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, 0);
 }
 
-#else
-#define tusb_omap_use_shared_dmareq(x, y)      do {} while (0)
-#define tusb_omap_free_shared_dmareq(x, y)     do {} while (0)
-#endif
-
 /*
  * See also musb_dma_completion in plat_uds.c and musb_g_[tx|rx]() in
  * musb_gadget.c.
 
        spin_lock_irqsave(&musb->lock, flags);
 
-       if (dmareq_works())
+       if (tusb_dma->multichannel)
                ch = chdat->ch;
        else
                ch = tusb_dma->ch;
                channel->actual_len += pio;
        }
 
-       if (!dmareq_works())
+       if (!tusb_dma->multichannel)
                tusb_omap_free_shared_dmareq(chdat);
 
        channel->status = MUSB_DMA_STATUS_FREE;
                return false;
        }
 
-
        chdat->transfer_len = len & ~0x1f;
 
        if (len < packet_sz)
        else
                chdat->transfer_packet_sz = packet_sz;
 
-       if (dmareq_works()) {
+       if (tusb_dma->multichannel) {
                ch = chdat->ch;
                dmareq = chdat->dmareq;
                sync_dev = chdat->sync_dev;
        struct tusb_omap_dma_ch *chdat = to_chdat(channel);
        struct tusb_omap_dma    *tusb_dma = chdat->tusb_dma;
 
-       if (!dmareq_works()) {
+       if (!tusb_dma->multichannel) {
                if (tusb_dma->ch >= 0) {
                        omap_stop_dma(tusb_dma->ch);
                        omap_free_dma(tusb_dma->ch);
        channel->desired_mode = 0;
        channel->actual_len = 0;
 
-       if (dmareq_works()) {
+       if (tusb_dma->multichannel) {
                ret = tusb_omap_dma_allocate_dmareq(chdat);
                if (ret != 0)
                        goto free_dmareq;
                }
        }
 
-       if (!dmareq_works() && tusb_dma && tusb_dma->ch >= 0)
+       if (!tusb_dma->multichannel && tusb_dma && tusb_dma->ch >= 0)
                omap_free_dma(tusb_dma->ch);
 
        kfree(tusb_dma);
        tusb_dma->controller.channel_abort = tusb_omap_dma_abort;
        tusb_dma->controller.private_data = tusb_dma;
 
+       if (tusb_get_revision(musb) >= TUSB_REV_30)
+               tusb_dma->multichannel = 1;
+
        for (i = 0; i < MAX_DMAREQ; i++) {
                struct dma_channel      *ch;
                struct tusb_omap_dma_ch *chdat;