]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/musb/musb_core.c
USB: musb free_irq bugfix
[linux-2.6-omap-h63xx.git] / drivers / usb / musb / musb_core.c
index de7f8bec6bdeff69dd898378624d00f9ae940ec4..2cc34fa05b7391813cb386342849b15bab714bc5 100644 (file)
@@ -148,7 +148,8 @@ static inline struct musb *dev_to_musb(struct device *dev)
 
 /*-------------------------------------------------------------------------*/
 
-#ifndef CONFIG_USB_TUSB6010
+#if !defined(CONFIG_USB_TUSB6010) && !defined(CONFIG_BLACKFIN)
+
 /*
  * Load an endpoint's FIFO
  */
@@ -1124,25 +1125,25 @@ fifo_setup(struct musb *musb, struct musb_hw_ep  *hw_ep,
 #endif
        switch (cfg->style) {
        case FIFO_TX:
-               musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
-               musb_writew(mbase, MUSB_TXFIFOADD, c_off);
+               musb_write_txfifosz(mbase, c_size);
+               musb_write_txfifoadd(mbase, c_off);
                hw_ep->tx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
                hw_ep->max_packet_sz_tx = maxpacket;
                break;
        case FIFO_RX:
-               musb_writeb(mbase, MUSB_RXFIFOSZ, c_size);
-               musb_writew(mbase, MUSB_RXFIFOADD, c_off);
+               musb_write_rxfifosz(mbase, c_size);
+               musb_write_rxfifoadd(mbase, c_off);
                hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
                hw_ep->max_packet_sz_rx = maxpacket;
                break;
        case FIFO_RXTX:
-               musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
-               musb_writew(mbase, MUSB_TXFIFOADD, c_off);
+               musb_write_txfifosz(mbase, c_size);
+               musb_write_txfifoadd(mbase, c_off);
                hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
                hw_ep->max_packet_sz_rx = maxpacket;
 
-               musb_writeb(mbase, MUSB_RXFIFOSZ, c_size);
-               musb_writew(mbase, MUSB_RXFIFOADD, c_off);
+               musb_write_rxfifosz(mbase, c_size);
+               musb_write_rxfifoadd(mbase, c_off);
                hw_ep->tx_double_buffered = hw_ep->rx_double_buffered;
                hw_ep->max_packet_sz_tx = maxpacket;
 
@@ -1212,7 +1213,7 @@ static int __init ep_config_from_table(struct musb *musb)
                if (epn >= musb->config->num_eps) {
                        pr_debug("%s: invalid ep %d\n",
                                        musb_driver_name, epn);
-                       continue;
+                       return -EINVAL;
                }
                offset = fifo_setup(musb, hw_ep + epn, cfg++, offset);
                if (offset < 0) {
@@ -1246,9 +1247,10 @@ static int __init ep_config_from_table(struct musb *musb)
  */
 static int __init ep_config_from_hw(struct musb *musb)
 {
-       u8 epnum = 0, reg;
+       u8 epnum = 0;
        struct musb_hw_ep *hw_ep;
        void *mbase = musb->mregs;
+       int ret = 0;
 
        DBG(2, "<== static silicon ep config\n");
 
@@ -1258,26 +1260,9 @@ static int __init ep_config_from_hw(struct musb *musb)
                musb_ep_select(mbase, epnum);
                hw_ep = musb->endpoints + epnum;
 
-               /* read from core using indexed model */
-               reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE);
-               if (!reg) {
-                       /* 0's returned when no more endpoints */
+               ret = musb_read_fifosize(musb, hw_ep, epnum);
+               if (ret < 0)
                        break;
-               }
-               musb->nr_endpoints++;
-               musb->epmask |= (1 << epnum);
-
-               hw_ep->max_packet_sz_tx = 1 << (reg & 0x0f);
-
-               /* shared TX/RX FIFO? */
-               if ((reg & 0xf0) == 0xf0) {
-                       hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx;
-                       hw_ep->is_shared_fifo = true;
-                       continue;
-               } else {
-                       hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4);
-                       hw_ep->is_shared_fifo = false;
-               }
 
                /* FIXME set up hw_ep->{rx,tx}_double_buffered */
 
@@ -1326,7 +1311,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
 
        /* log core options (read using indexed model) */
        musb_ep_select(mbase, 0);
-       reg = musb_readb(mbase, 0x10 + MUSB_CONFIGDATA);
+       reg = musb_read_configdata(mbase);
 
        strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8");
        if (reg & MUSB_CONFIGDATA_DYNFIFO)
@@ -1391,7 +1376,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
        }
 
        /* log release info */
-       hwvers = musb_readw(mbase, MUSB_HWVERS);
+       hwvers = musb_read_hwvers(mbase);
        rev_major = (hwvers >> 10) & 0x1f;
        rev_minor = hwvers & 0x3ff;
        snprintf(aRevision, 32, "%d.%d%s", rev_major,
@@ -1400,8 +1385,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
                        musb_driver_name, type, aRevision, aDate);
 
        /* configure ep0 */
-       musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE;
-       musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE;
+       musb_configure_ep0(musb);
 
        /* discover endpoint configuration */
        musb->nr_endpoints = 1;
@@ -1445,7 +1429,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
 
                hw_ep->regs = MUSB_EP_OFFSET(i, 0) + mbase;
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
-               hw_ep->target_regs = MUSB_BUSCTL_OFFSET(i, 0) + mbase;
+               hw_ep->target_regs = musb_read_target_reg_base(i, mbase);
                hw_ep->rx_reinit = 1;
                hw_ep->tx_reinit = 1;
 #endif
@@ -1813,7 +1797,6 @@ allocate_instance(struct device *dev,
        for (epnum = 0, ep = musb->endpoints;
                        epnum < musb->config->num_eps;
                        epnum++, ep++) {
-
                ep->musb = musb;
                ep->epnum = epnum;
        }
@@ -1842,7 +1825,8 @@ static void musb_free(struct musb *musb)
 #endif
 
        if (musb->nIrq >= 0) {
-               disable_irq_wake(musb->nIrq);
+               if (musb->irq_wake)
+                       disable_irq_wake(musb->nIrq);
                free_irq(musb->nIrq, musb);
        }
        if (is_dma_capable() && musb->dma_controller) {
@@ -1994,8 +1978,12 @@ bad_config:
        }
        musb->nIrq = nIrq;
 /* FIXME this handles wakeup irqs wrong */
-       if (enable_irq_wake(nIrq) == 0)
+       if (enable_irq_wake(nIrq) == 0) {
+               musb->irq_wake = 1;
                device_init_wakeup(dev, 1);
+       } else {
+               musb->irq_wake = 0;
+       }
 
        pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n",
                        musb_driver_name,