Merge branch 'for-greg' of git://gitorious.org/usb/usb into usb-linus
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 13 Apr 2011 21:32:07 +0000 (14:32 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 13 Apr 2011 21:33:52 +0000 (14:33 -0700)
* 'for-greg' of git://gitorious.org/usb/usb:
  USB: musb: blackfin: work around anomaly 05000450
  usb: musb: Fix the crash issue during reboot
  usb: musb: gadget: check the correct list_head
  usb: musb: temporarily make it bool
  USB: musb: dereferencing an iomem pointer
  USB: musb: silence printk format warning
  USB: musb: using 0 instead of NULL
  USB: musb: add missing unlock in cppi_interrupt()
  usb: musb: ux500: copy dma mask from platform device to musb device
  usb: musb: clear AUTOSET while clearing DMAENAB

drivers/usb/musb/Kconfig
drivers/usb/musb/blackfin.c
drivers/usb/musb/cppi_dma.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musbhsdma.c
drivers/usb/musb/ux500.c

index 4cbb7e4..74073b3 100644 (file)
@@ -14,7 +14,7 @@ config USB_MUSB_HDRC
        select TWL4030_USB if MACH_OMAP_3430SDP
        select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
        select USB_OTG_UTILS
-       tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
+       bool 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
        help
          Say Y here if your system has a dual role high speed USB
          controller based on the Mentor Graphics silicon IP.  Then
@@ -30,8 +30,8 @@ config USB_MUSB_HDRC
 
          If you do not know what this is, please say N.
 
-         To compile this driver as a module, choose M here; the
-         module will be called "musb-hdrc".
+#        To compile this driver as a module, choose M here; the
+#        module will be called "musb-hdrc".
 
 choice
        prompt "Platform Glue Layer"
index 52312e8..8e2a1ff 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/cacheflush.h>
 
 #include "musb_core.h"
+#include "musbhsdma.h"
 #include "blackfin.h"
 
 struct bfin_glue {
@@ -332,6 +333,27 @@ static int bfin_musb_set_mode(struct musb *musb, u8 musb_mode)
        return -EIO;
 }
 
+static int bfin_musb_adjust_channel_params(struct dma_channel *channel,
+                               u16 packet_sz, u8 *mode,
+                               dma_addr_t *dma_addr, u32 *len)
+{
+       struct musb_dma_channel *musb_channel = channel->private_data;
+
+       /*
+        * Anomaly 05000450 might cause data corruption when using DMA
+        * MODE 1 transmits with short packet.  So to work around this,
+        * we truncate all MODE 1 transfers down to a multiple of the
+        * max packet size, and then do the last short packet transfer
+        * (if there is any) using MODE 0.
+        */
+       if (ANOMALY_05000450) {
+               if (musb_channel->transmit && *mode == 1)
+                       *len = *len - (*len % packet_sz);
+       }
+
+       return 0;
+}
+
 static void bfin_musb_reg_init(struct musb *musb)
 {
        if (ANOMALY_05000346) {
@@ -430,6 +452,8 @@ static const struct musb_platform_ops bfin_ops = {
 
        .vbus_status    = bfin_musb_vbus_status,
        .set_vbus       = bfin_musb_set_vbus,
+
+       .adjust_channel_params = bfin_musb_adjust_channel_params,
 };
 
 static u64 bfin_dmamask = DMA_BIT_MASK(32);
index de55a3c..ab434fb 100644 (file)
@@ -597,12 +597,12 @@ cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx)
                length = min(n_bds * maxpacket, length);
        }
 
-       DBG(4, "TX DMA%d, pktSz %d %s bds %d dma 0x%x len %u\n",
+       DBG(4, "TX DMA%d, pktSz %d %s bds %d dma 0x%llx len %u\n",
                        tx->index,
                        maxpacket,
                        rndis ? "rndis" : "transparent",
                        n_bds,
-                       addr, length);
+                       (unsigned long long)addr, length);
 
        cppi_rndis_update(tx, 0, musb->ctrl_base, rndis);
 
@@ -820,7 +820,7 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket)
        length = min(n_bds * maxpacket, length);
 
        DBG(4, "RX DMA%d seg, maxp %d %s bds %d (cnt %d) "
-                       "dma 0x%x len %u %u/%u\n",
+                       "dma 0x%llx len %u %u/%u\n",
                        rx->index, maxpacket,
                        onepacket
                                ? (is_rndis ? "rndis" : "onepacket")
@@ -829,7 +829,8 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket)
                        musb_readl(tibase,
                                DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4))
                                        & 0xffff,
-                       addr, length, rx->channel.actual_len, rx->buf_len);
+                       (unsigned long long)addr, length,
+                       rx->channel.actual_len, rx->buf_len);
 
        /* only queue one segment at a time, since the hardware prevents
         * correct queue shutdown after unexpected short packets
@@ -1039,9 +1040,9 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch)
                if (!completed && (bd->hw_options & CPPI_OWN_SET))
                        break;
 
-               DBG(5, "C/RXBD %08x: nxt %08x buf %08x "
+               DBG(5, "C/RXBD %llx: nxt %08x buf %08x "
                        "off.len %08x opt.len %08x (%d)\n",
-                       bd->dma, bd->hw_next, bd->hw_bufp,
+                       (unsigned long long)bd->dma, bd->hw_next, bd->hw_bufp,
                        bd->hw_off_len, bd->hw_options,
                        rx->channel.actual_len);
 
@@ -1111,11 +1112,12 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch)
                musb_ep_select(cppi->mregs, rx->index + 1);
                csr = musb_readw(regs, MUSB_RXCSR);
                if (csr & MUSB_RXCSR_DMAENAB) {
-                       DBG(4, "list%d %p/%p, last %08x%s, csr %04x\n",
+                       DBG(4, "list%d %p/%p, last %llx%s, csr %04x\n",
                                rx->index,
                                rx->head, rx->tail,
                                rx->last_processed
-                                       ? rx->last_processed->dma
+                                       ? (unsigned long long)
+                                               rx->last_processed->dma
                                        : 0,
                                completed ? ", completed" : "",
                                csr);
@@ -1167,8 +1169,11 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id)
        tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG);
        rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG);
 
-       if (!tx && !rx)
+       if (!tx && !rx) {
+               if (cppi->irq)
+                       spin_unlock_irqrestore(&musb->lock, flags);
                return IRQ_NONE;
+       }
 
        DBG(4, "CPPI IRQ Tx%x Rx%x\n", tx, rx);
 
@@ -1199,7 +1204,7 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id)
                 */
                if (NULL == bd) {
                        DBG(1, "null BD\n");
-                       tx_ram->tx_complete = 0;
+                       musb_writel(&tx_ram->tx_complete, 0, 0);
                        continue;
                }
 
@@ -1452,7 +1457,7 @@ static int cppi_channel_abort(struct dma_channel *channel)
                 *    compare mode by writing 1 to the tx_complete register.
                 */
                cppi_reset_tx(tx_ram, 1);
-               cppi_ch->head = 0;
+               cppi_ch->head = NULL;
                musb_writel(&tx_ram->tx_complete, 0, 1);
                cppi_dump_tx(5, cppi_ch, " (done teardown)");
 
index 630ae7f..f10ff00 100644 (file)
@@ -1030,6 +1030,7 @@ static void musb_shutdown(struct platform_device *pdev)
        struct musb     *musb = dev_to_musb(&pdev->dev);
        unsigned long   flags;
 
+       pm_runtime_get_sync(musb->controller);
        spin_lock_irqsave(&musb->lock, flags);
        musb_platform_disable(musb);
        musb_generic_disable(musb);
@@ -1040,6 +1041,7 @@ static void musb_shutdown(struct platform_device *pdev)
        musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
        musb_platform_exit(musb);
 
+       pm_runtime_put(musb->controller);
        /* FIXME power down */
 }
 
index 4bd9e21..0e053b5 100644 (file)
@@ -261,6 +261,7 @@ enum musb_g_ep0_state {
  * @try_ilde:  tries to idle the IP
  * @vbus_status: returns vbus status if possible
  * @set_vbus:  forces vbus status
+ * @channel_program: pre check for standard dma channel_program func
  */
 struct musb_platform_ops {
        int     (*init)(struct musb *musb);
@@ -274,6 +275,10 @@ struct musb_platform_ops {
 
        int     (*vbus_status)(struct musb *musb);
        void    (*set_vbus)(struct musb *musb, int on);
+
+       int     (*adjust_channel_params)(struct dma_channel *channel,
+                               u16 packet_sz, u8 *mode,
+                               dma_addr_t *dma_addr, u32 *len);
 };
 
 /*
index 98519c5..6dfbf9f 100644 (file)
@@ -535,7 +535,7 @@ void musb_g_tx(struct musb *musb, u8 epnum)
                        is_dma = 1;
                        csr |= MUSB_TXCSR_P_WZC_BITS;
                        csr &= ~(MUSB_TXCSR_DMAENAB | MUSB_TXCSR_P_UNDERRUN |
-                                MUSB_TXCSR_TXPKTRDY);
+                                MUSB_TXCSR_TXPKTRDY | MUSB_TXCSR_AUTOSET);
                        musb_writew(epio, MUSB_TXCSR, csr);
                        /* Ensure writebuffer is empty. */
                        csr = musb_readw(epio, MUSB_TXCSR);
@@ -1296,7 +1296,7 @@ static int musb_gadget_dequeue(struct usb_ep *ep, struct usb_request *request)
        }
 
        /* if the hardware doesn't have the request, easy ... */
-       if (musb_ep->req_list.next != &request->list || musb_ep->busy)
+       if (musb_ep->req_list.next != &req->list || musb_ep->busy)
                musb_g_giveback(musb_ep, request, -ECONNRESET);
 
        /* ... else abort the dma transfer ... */
index 0144a2d..d281792 100644 (file)
@@ -169,6 +169,14 @@ static int dma_channel_program(struct dma_channel *channel,
        BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
                channel->status == MUSB_DMA_STATUS_BUSY);
 
+       /* Let targets check/tweak the arguments */
+       if (musb->ops->adjust_channel_params) {
+               int ret = musb->ops->adjust_channel_params(channel,
+                       packet_sz, &mode, &dma_addr, &len);
+               if (ret)
+                       return ret;
+       }
+
        /*
         * The DMA engine in RTL1.8 and above cannot handle
         * DMA addresses that are not aligned to a 4 byte boundary.
index d6384e4..f7e04bf 100644 (file)
@@ -93,6 +93,8 @@ static int __init ux500_probe(struct platform_device *pdev)
        }
 
        musb->dev.parent                = &pdev->dev;
+       musb->dev.dma_mask              = pdev->dev.dma_mask;
+       musb->dev.coherent_dma_mask     = pdev->dev.coherent_dma_mask;
 
        glue->dev                       = &pdev->dev;
        glue->musb                      = musb;