]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/musb/plat_uds.c
ARM: OMAP: MUSB: IRQ reset: babble handling is host only
[linux-2.6-omap-h63xx.git] / drivers / usb / musb / plat_uds.c
index 7b516ad7f00bc7b5e36bf51a54858e76809e7d1c..dacf930c7ffe65a5753260405c55ae71a6a68382 100644 (file)
@@ -1,36 +1,36 @@
-/*****************************************************************
+/*
+ * MUSB OTG driver core code
+ *
  * Copyright 2005 Mentor Graphics Corporation
  * Copyright (C) 2005-2006 by Texas Instruments
- * Copyright (C) 2006 by Nokia Corporation
+ * Copyright (C) 2006-2007 Nokia Corporation
  *
- * This file is part of the Inventra Controller Driver for Linux.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
  *
- * The Inventra Controller Driver for Linux is free software; you
- * can redistribute it and/or modify it under the terms of the GNU
- * General Public License version 2 as published by the Free Software
- * Foundation.
- *
- * The Inventra Controller Driver for Linux is distributed in
- * the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
- * License for more details.
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with The Inventra Controller Driver for Linux ; if not,
- * write to the Free Software Foundation, Inc., 59 Temple Place,
- * Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * ANY DOWNLOAD, USE, REPRODUCTION, MODIFICATION OR DISTRIBUTION
- * OF THIS DRIVER INDICATES YOUR COMPLETE AND UNCONDITIONAL ACCEPTANCE
- * OF THOSE TERMS.THIS DRIVER IS PROVIDED "AS IS" AND MENTOR GRAPHICS
- * MAKES NO WARRANTIES, EXPRESS OR IMPLIED, RELATED TO THIS DRIVER.
- * MENTOR GRAPHICS SPECIFICALLY DISCLAIMS ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY; FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT.  MENTOR GRAPHICS DOES NOT PROVIDE SUPPORT
- * SERVICES OR UPDATES FOR THIS DRIVER, EVEN IF YOU ARE A MENTOR
- * GRAPHICS SUPPORT CUSTOMER.
- ******************************************************************/
+ */
 
 /*
  * Inventra (Multipoint) Dual-Role Controller Driver for Linux.
@@ -351,7 +351,7 @@ void musb_hnp_stop(struct musb *musb)
  * the order of the tests is specified in the manual
  *
  * @param musb instance pointer
- * @param bIntrUSB register contents
+ * @param int_usb register contents
  * @param devctl
  * @param power
  */
@@ -360,7 +360,7 @@ void musb_hnp_stop(struct musb *musb)
                | MUSB_INTR_VBUSERROR | MUSB_INTR_CONNECT \
                | MUSB_INTR_RESET )
 
-static irqreturn_t musb_stage0_irq(struct musb * musb, u8 bIntrUSB,
+static irqreturn_t musb_stage0_irq(struct musb * musb, u8 int_usb,
                                u8 devctl, u8 power)
 {
        irqreturn_t handled = IRQ_NONE;
@@ -368,14 +368,14 @@ static irqreturn_t musb_stage0_irq(struct musb * musb, u8 bIntrUSB,
        void __iomem *mbase = musb->mregs;
 #endif
 
-       DBG(3, "<== Power=%02x, DevCtl=%02x, bIntrUSB=0x%x\n", power, devctl,
-               bIntrUSB);
+       DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl,
+               int_usb);
 
        /* in host mode, the peripheral may issue remote wakeup.
         * in peripheral mode, the host may resume the link.
         * spurious RESUME irqs happen too, paired with SUSPEND.
         */
-       if (bIntrUSB & MUSB_INTR_RESUME) {
+       if (int_usb & MUSB_INTR_RESUME) {
                handled = IRQ_HANDLED;
                DBG(3, "RESUME (%s)\n", otg_state_string(musb));
 
@@ -456,7 +456,7 @@ static irqreturn_t musb_stage0_irq(struct musb * musb, u8 bIntrUSB,
 
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
        /* see manual for the order of the tests */
-       if (bIntrUSB & MUSB_INTR_SESSREQ) {
+       if (int_usb & MUSB_INTR_SESSREQ) {
                DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb));
 
                /* IRQ arrives from ID pin sense or (later, if VBUS power
@@ -467,7 +467,7 @@ static irqreturn_t musb_stage0_irq(struct musb * musb, u8 bIntrUSB,
                 * a_wait_vrise_tmout triggers VBUS_ERROR transitions
                 */
                musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
-               musb->ep0_stage = MGC_END0_START;
+               musb->ep0_stage = MUSB_EP0_START;
                musb->xceiv.state = OTG_STATE_A_IDLE;
                MUSB_HST_MODE(musb);
                musb_set_vbus(musb, 1);
@@ -475,7 +475,7 @@ static irqreturn_t musb_stage0_irq(struct musb * musb, u8 bIntrUSB,
                handled = IRQ_HANDLED;
        }
 
-       if (bIntrUSB & MUSB_INTR_VBUSERROR) {
+       if (int_usb & MUSB_INTR_VBUSERROR) {
                int     ignore = 0;
 
                /* During connection as an A-Device, we may see a short
@@ -543,23 +543,22 @@ static irqreturn_t musb_stage0_irq(struct musb * musb, u8 bIntrUSB,
                handled = IRQ_HANDLED;
        }
 
-       if (bIntrUSB & MUSB_INTR_CONNECT) {
+       if (int_usb & MUSB_INTR_CONNECT) {
                struct usb_hcd *hcd = musb_to_hcd(musb);
 
                handled = IRQ_HANDLED;
                musb->is_active = 1;
                set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
 
-               musb->ep0_stage = MGC_END0_START;
+               musb->ep0_stage = MUSB_EP0_START;
 
 #ifdef CONFIG_USB_MUSB_OTG
                /* flush endpoints when transitioning from Device Mode */
                if (is_peripheral_active(musb)) {
                        // REVISIT HNP; just force disconnect
                }
-               musb->delay_port_power_off = FALSE;
-               musb_writew(mbase, MUSB_INTRTXE, musb->wEndMask);
-               musb_writew(mbase, MUSB_INTRRXE, musb->wEndMask & 0xfffe);
+               musb_writew(mbase, MUSB_INTRTXE, musb->epmask);
+               musb_writew(mbase, MUSB_INTRRXE, musb->epmask & 0xfffe);
                musb_writeb(mbase, MUSB_INTRUSBE, 0xf7);
 #endif
                musb->port1_status &= ~(USB_PORT_STAT_LOW_SPEED
@@ -603,7 +602,8 @@ static irqreturn_t musb_stage0_irq(struct musb * musb, u8 bIntrUSB,
        /* mentor saves a bit: bus reset and babble share the same irq.
         * only host sees babble; only peripheral sees bus reset.
         */
-       if (bIntrUSB & MUSB_INTR_RESET) {
+       if (int_usb & MUSB_INTR_RESET) {
+#ifdef CONFIG_USB_MUSB_HDRC_HCD
                if (devctl & MUSB_DEVCTL_HM) {
                        /*
                         * Looks like non-HS BABBLE can be ignored, but
@@ -618,7 +618,9 @@ static irqreturn_t musb_stage0_irq(struct musb * musb, u8 bIntrUSB,
                                ERR("Stopping host session because of babble\n");
                                musb_writeb(mbase, MUSB_DEVCTL, 0);
                        }
-               } else {
+               } else
+#endif /* CONFIG_USB_MUSB_HDRC_HCD */
+               {
                        DBG(1, "BUS RESET\n");
 
                        musb_g_reset(musb);
@@ -638,11 +640,11 @@ static irqreturn_t musb_stage0_irq(struct musb * musb, u8 bIntrUSB,
  * the order of the tests is specified in the manual
  *
  * @param musb instance pointer
- * @param bIntrUSB register contents
+ * @param int_usb register contents
  * @param devctl
  * @param power
  */
-static irqreturn_t musb_stage2_irq(struct musb * musb, u8 bIntrUSB,
+static irqreturn_t musb_stage2_irq(struct musb * musb, u8 int_usb,
                                u8 devctl, u8 power)
 {
        irqreturn_t handled = IRQ_NONE;
@@ -659,24 +661,24 @@ static irqreturn_t musb_stage2_irq(struct musb * musb, u8 bIntrUSB,
  * endpoints, relies on TX/RX interval registers, and isn't claimed
  * to support ISO transfers yet.
  */
-       if (bIntrUSB & MUSB_INTR_SOF) {
+       if (int_usb & MUSB_INTR_SOF) {
                void __iomem *mbase = musb->mregs;
                struct musb_hw_ep       *ep;
                u8 epnum;
-               u16 wFrame;
+               u16 frame;
 
                DBG(6, "START_OF_FRAME\n");
                handled = IRQ_HANDLED;
 
                /* start any periodic Tx transfers waiting for current frame */
-               wFrame = musb_readw(mbase, MUSB_FRAME);
+               frame = musb_readw(mbase, MUSB_FRAME);
                ep = musb->endpoints;
                for (epnum = 1; (epnum < musb->nr_endpoints)
-                                       && (musb->wEndMask >= (1 << epnum));
+                                       && (musb->epmask >= (1 << epnum));
                                epnum++, ep++) {
                        // FIXME handle framecounter wraps (12 bits)
                        // eliminate duplicated StartUrb logic
-                       if (ep->dwWaitFrame >= wFrame) {
+                       if (ep->dwWaitFrame >= frame) {
                                ep->dwWaitFrame = 0;
                                printk("SOF --> periodic TX%s on %d\n",
                                        ep->tx_channel ? " DMA" : "",
@@ -690,7 +692,7 @@ static irqreturn_t musb_stage2_irq(struct musb * musb, u8 bIntrUSB,
        }
 #endif
 
-       if ((bIntrUSB & MUSB_INTR_DISCONNECT) && !musb->ignore_disconnect) {
+       if ((int_usb & MUSB_INTR_DISCONNECT) && !musb->ignore_disconnect) {
                DBG(1, "DISCONNECT (%s) as %s, devctl %02x\n",
                                otg_state_string(musb),
                                MUSB_MODE(musb), devctl);
@@ -731,15 +733,17 @@ static irqreturn_t musb_stage2_irq(struct musb * musb, u8 bIntrUSB,
                schedule_work(&musb->irq_work);
        }
 
-       if (bIntrUSB & MUSB_INTR_SUSPEND) {
+       if (int_usb & MUSB_INTR_SUSPEND) {
                DBG(1, "SUSPEND (%s) devctl %02x power %02x\n",
                                otg_state_string(musb), devctl, power);
                handled = IRQ_HANDLED;
 
                switch (musb->xceiv.state) {
+#ifdef CONFIG_USB_MUSB_OTG
                case OTG_STATE_A_PERIPHERAL:
                        musb_hnp_stop(musb);
                        break;
+#endif
                case OTG_STATE_B_PERIPHERAL:
                        musb_g_suspend(musb);
                        musb->is_active = is_otg_enabled(musb)
@@ -792,8 +796,8 @@ void musb_start(struct musb *musb)
        DBG(2, "<== devctl %02x\n", devctl);
 
        /*  Set INT enable registers, enable interrupts */
-       musb_writew(regs, MUSB_INTRTXE, musb->wEndMask);
-       musb_writew(regs, MUSB_INTRRXE, musb->wEndMask & 0xfffe);
+       musb_writew(regs, MUSB_INTRTXE, musb->epmask);
+       musb_writew(regs, MUSB_INTRRXE, musb->epmask & 0xfffe);
        musb_writeb(regs, MUSB_INTRUSBE, 0xf7);
 
        musb_writeb(regs, MUSB_TESTMODE, 0);
@@ -1086,7 +1090,7 @@ fifo_setup(struct musb *musb, struct musb_hw_ep  *hw_ep,
        /* NOTE rx and tx endpoint irqs aren't managed separately,
         * which happens to be ok
         */
-       musb->wEndMask |= (1 << hw_ep->epnum);
+       musb->epmask |= (1 << hw_ep->epnum);
 
        return offset + (maxpacket << ((c_size & MUSB_FIFOSZ_DPB) ? 1 : 0));
 }
@@ -1198,7 +1202,7 @@ static int __init ep_config_from_hw(struct musb *musb)
                        break;
                }
                musb->nr_endpoints++;
-               musb->wEndMask |= (1 << epnum);
+               musb->epmask |= (1 << epnum);
 
                hw_ep->max_packet_sz_tx = 1 << (reg & 0x0f);
 
@@ -1244,14 +1248,14 @@ enum { MUSB_CONTROLLER_MHDRC, MUSB_CONTROLLER_HDRC, };
 /* Initialize MUSB (M)HDRC part of the USB hardware subsystem;
  * configure endpoints, or take their config from silicon
  */
-static int __init musb_core_init(u16 wType, struct musb *musb)
+static int __init musb_core_init(u16 musb_type, struct musb *musb)
 {
 #ifdef MUSB_AHB_ID
-       u32 dwData;
+       u32 data;
 #endif
        u8 reg;
        char *type;
-       u16 wRelease, wRelMajor, wRelMinor;
+       u16 hwvers, rev_major, rev_minor;
        char aInfo[78], aRevision[32], aDate[12];
        void __iomem    *mbase = musb->mregs;
        int             status = 0;
@@ -1297,20 +1301,20 @@ static int __init musb_core_init(u16 wType, struct musb *musb)
                        musb_driver_name, reg, aInfo);
 
 #ifdef MUSB_AHB_ID
-       dwData = musb_readl(mbase, 0x404);
-       sprintf(aDate, "%04d-%02x-%02x", (dwData & 0xffff),
-               (dwData >> 16) & 0xff, (dwData >> 24) & 0xff);
+       data = musb_readl(mbase, 0x404);
+       sprintf(aDate, "%04d-%02x-%02x", (data & 0xffff),
+               (data >> 16) & 0xff, (data >> 24) & 0xff);
        /* FIXME ID2 and ID3 are unused */
-       dwData = musb_readl(mbase, 0x408);
-       printk("ID2=%lx\n", (long unsigned)dwData);
-       dwData = musb_readl(mbase, 0x40c);
-       printk("ID3=%lx\n", (long unsigned)dwData);
+       data = musb_readl(mbase, 0x408);
+       printk("ID2=%lx\n", (long unsigned)data);
+       data = musb_readl(mbase, 0x40c);
+       printk("ID3=%lx\n", (long unsigned)data);
        reg = musb_readb(mbase, 0x400);
-       wType = ('M' == reg) ? MUSB_CONTROLLER_MHDRC : MUSB_CONTROLLER_HDRC;
+       musb_type = ('M' == reg) ? MUSB_CONTROLLER_MHDRC : MUSB_CONTROLLER_HDRC;
 #else
        aDate[0] = 0;
 #endif
-       if (MUSB_CONTROLLER_MHDRC == wType) {
+       if (MUSB_CONTROLLER_MHDRC == musb_type) {
                musb->is_multipoint = 1;
                type = "M";
        } else {
@@ -1326,21 +1330,21 @@ static int __init musb_core_init(u16 wType, struct musb *musb)
        }
 
        /* log release info */
-       wRelease = musb_readw(mbase, MUSB_HWVERS);
-       wRelMajor = (wRelease >> 10) & 0x1f;
-       wRelMinor = wRelease & 0x3ff;
-       snprintf(aRevision, 32, "%d.%d%s", wRelMajor,
-               wRelMinor, (wRelease & 0x8000) ? "RC" : "");
+       hwvers = musb_readw(mbase, MUSB_HWVERS);
+       rev_major = (hwvers >> 10) & 0x1f;
+       rev_minor = hwvers & 0x3ff;
+       snprintf(aRevision, 32, "%d.%d%s", rev_major,
+               rev_minor, (hwvers & 0x8000) ? "RC" : "");
        printk(KERN_DEBUG "%s: %sHDRC RTL version %s %s\n",
                        musb_driver_name, type, aRevision, aDate);
 
        /* configure ep0 */
-       musb->endpoints[0].max_packet_sz_tx = MGC_END0_FIFOSIZE;
-       musb->endpoints[0].max_packet_sz_rx = MGC_END0_FIFOSIZE;
+       musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE;
+       musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE;
 
        /* discover endpoint configuration */
        musb->nr_endpoints = 1;
-       musb->wEndMask = 1;
+       musb->epmask = 1;
 
        if (reg & MUSB_CONFIGDATA_DYNFIFO) {
                if (can_dynfifo())
@@ -1378,9 +1382,9 @@ static int __init musb_core_init(u16 wType, struct musb *musb)
                        hw_ep->conf = mbase + 0x400 + (((i - 1) & 0xf) << 2);
 #endif
 
-               hw_ep->regs = MGC_END_OFFSET(i, 0) + mbase;
+               hw_ep->regs = MUSB_EP_OFFSET(i, 0) + mbase;
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
-               hw_ep->target_regs = MGC_BUSCTL_OFFSET(i, 0) + mbase;
+               hw_ep->target_regs = MUSB_BUSCTL_OFFSET(i, 0) + mbase;
                hw_ep->rx_reinit = 1;
                hw_ep->tx_reinit = 1;
 #endif
@@ -1539,7 +1543,7 @@ static int __initdata use_dma = 1;
 module_param(use_dma, bool, 0);
 MODULE_PARM_DESC(use_dma, "enable/disable use of DMA");
 
-void musb_dma_completion(struct musb *musb, u8 epnum, u8 bTransmit)
+void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit)
 {
        u8      devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
 
@@ -1557,7 +1561,7 @@ void musb_dma_completion(struct musb *musb, u8 epnum, u8 bTransmit)
 #endif
        } else {
                /* endpoints 1..15 */
-               if (bTransmit) {
+               if (transmit) {
                        if (devctl & MUSB_DEVCTL_HM) {
                                if (is_host_capable())
                                        musb_host_tx(musb, epnum);
@@ -1708,7 +1712,6 @@ musb_srp_store(struct device *dev, struct device_attribute *attr,
                const char *buf, size_t n)
 {
        struct musb     *musb=dev_to_musb(dev);
-       unsigned long   flags;
        unsigned short  srp;
 
        if (sscanf(buf, "%hu", &srp) != 1
@@ -1717,10 +1720,8 @@ musb_srp_store(struct device *dev, struct device_attribute *attr,
                return -EINVAL;
        }
 
-       spin_lock_irqsave(&musb->lock, flags);
        if (srp == 1)
                musb_g_wakeup(musb);
-       spin_unlock_irqrestore(&musb->lock, flags);
 
        return n;
 }