]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 3 Mar 2010 16:48:58 +0000 (08:48 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 3 Mar 2010 16:48:58 +0000 (08:48 -0800)
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (220 commits)
  USB: backlight, appledisplay: fix incomplete registration failure handling
  USB: pl2303: remove unnecessary reset of usb_device in urbs
  USB: ftdi_sio: remove obsolete check in unthrottle
  USB: ftdi_sio: remove unused tx_bytes counter
  USB: qcaux: driver for auxiliary serial ports on Qualcomm devices
  USB: pl2303: initial TIOCGSERIAL support
  USB: option: add Longcheer/Longsung vendor ID
  USB: fix I2C API usage in ohci-pnx4008.
  USB: usbmon: mask seconds properly in text API
  USB: sisusbvga: no unnecessary GFP_ATOMIC
  USB: storage: onetouch: unnecessary GFP_ATOMIC
  USB: serial: ftdi: add CONTEC vendor and product id
  USB: remove references to port->port.count from the serial drivers
  USB: tty: Prune uses of tty_request_room in the USB layer
  USB: tty: Add a function to insert a string of characters with the same flag
  USB: don't read past config->interface[] if usb_control_msg() fails in usb_reset_configuration()
  USB: tty: kill request_room for USB ACM class
  USB: tty: sort out the request_room handling for whiteheat
  USB: storage: fix misplaced parenthesis
  USB: vstusb.c: removal of driver for Vernier Software & Technology, Inc., devices and spectrometers
  ...

1  2 
arch/arm/configs/rx51_defconfig
drivers/char/tty_buffer.c
drivers/usb/Kconfig
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_core.h
drivers/usb/serial/keyspan_pda.c
include/linux/usb/musb.h
include/linux/usb/otg.h

index 426ae948aefe69020cc2f8e4ede1e0459d51a3a1,72e27d8401e617410be90957c8d749d35946abe4..193bd334fbbffbfd08c18955107339040980c962
@@@ -445,6 -445,8 +445,8 @@@ CONFIG_IP_NF_FILTER=
  # CONFIG_LAPB is not set
  # CONFIG_ECONET is not set
  # CONFIG_WAN_ROUTER is not set
+ CONFIG_PHONET=y
+ # CONFIG_IEEE802154 is not set
  # CONFIG_NET_SCHED is not set
  # CONFIG_DCB is not set
  
@@@ -1325,27 -1327,34 +1327,34 @@@ CONFIG_USB_GADGET_SELECTED=
  # CONFIG_USB_GADGET_LH7A40X is not set
  # CONFIG_USB_GADGET_OMAP is not set
  # CONFIG_USB_GADGET_PXA25X is not set
+ # CONFIG_USB_GADGET_R8A66597 is not set
  # CONFIG_USB_GADGET_PXA27X is not set
- # CONFIG_USB_GADGET_S3C2410 is not set
+ # CONFIG_USB_GADGET_S3C_HSOTG is not set
  # CONFIG_USB_GADGET_IMX is not set
+ # CONFIG_USB_GADGET_S3C2410 is not set
  # CONFIG_USB_GADGET_M66592 is not set
  # CONFIG_USB_GADGET_AMD5536UDC is not set
  # CONFIG_USB_GADGET_FSL_QE is not set
  # CONFIG_USB_GADGET_CI13XXX is not set
  # CONFIG_USB_GADGET_NET2280 is not set
  # CONFIG_USB_GADGET_GOKU is not set
+ # CONFIG_USB_GADGET_LANGWELL is not set
  # CONFIG_USB_GADGET_DUMMY_HCD is not set
  CONFIG_USB_GADGET_DUALSPEED=y
  CONFIG_USB_ZERO=m
  # CONFIG_USB_ZERO_HNPTEST is not set
+ # CONFIG_USB_AUDIO is not set
  # CONFIG_USB_ETH is not set
  # CONFIG_USB_GADGETFS is not set
  CONFIG_USB_FILE_STORAGE=m
  # CONFIG_USB_FILE_STORAGE_TEST is not set
+ # CONFIG_USB_MASS_STORAGE is not set
  # CONFIG_USB_G_SERIAL is not set
  # CONFIG_USB_MIDI_GADGET is not set
  # CONFIG_USB_G_PRINTER is not set
  # CONFIG_USB_CDC_COMPOSITE is not set
+ CONFIG_USB_G_NOKIA=m
+ # CONFIG_USB_G_MULTI is not set
  
  #
  # OTG and related infrastructure
@@@ -1354,7 -1363,7 +1363,7 @@@ CONFIG_USB_OTG_UTILS=
  # CONFIG_USB_GPIO_VBUS is not set
  # CONFIG_ISP1301_OMAP is not set
  CONFIG_TWL4030_USB=y
 -CONFIG_MMC=y
 +CONFIG_MMC=m
  # CONFIG_MMC_DEBUG is not set
  # CONFIG_MMC_UNSAFE_RESUME is not set
  
  # MMC/SD/SDIO Card Drivers
  #
  CONFIG_MMC_BLOCK=m
 -CONFIG_MMC_BLOCK_BOUNCE=y
 +# CONFIG_MMC_BLOCK_BOUNCE is not set
  # CONFIG_SDIO_UART is not set
  # CONFIG_MMC_TEST is not set
  
index f27c4d6d956ec7e6501a6990ffd81b736750d478,4c133459ab7e5b2efcd3c364aad15b179dc83008..af8d97715728b4829ec152dcd22b5fa4516e9bbc
@@@ -231,9 -231,10 +231,10 @@@ int tty_buffer_request_room(struct tty_
  EXPORT_SYMBOL_GPL(tty_buffer_request_room);
  
  /**
-  *    tty_insert_flip_string  -       Add characters to the tty buffer
+  *    tty_insert_flip_string_fixed_flag - Add characters to the tty buffer
   *    @tty: tty structure
   *    @chars: characters
+  *    @flag: flag value for each character
   *    @size: size
   *
   *    Queue a series of bytes to the tty buffering. All the characters
   *    Locking: Called functions may take tty->buf.lock
   */
  
- int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
-                               size_t size)
+ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
+               const unsigned char *chars, char flag, size_t size)
  {
        int copied = 0;
        do {
 -              int space = tty_buffer_request_room(tty, size - copied);
 +              int goal = min(size - copied, TTY_BUFFER_PAGE);
 +              int space = tty_buffer_request_room(tty, goal);
                struct tty_buffer *tb = tty->buf.tail;
                /* If there is no space then tb may be NULL */
                if (unlikely(space == 0))
                        break;
                memcpy(tb->char_buf_ptr + tb->used, chars, space);
-               memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
+               memset(tb->flag_buf_ptr + tb->used, flag, space);
                tb->used += space;
                copied += space;
                chars += space;
        } while (unlikely(size > copied));
        return copied;
  }
- EXPORT_SYMBOL(tty_insert_flip_string);
+ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag);
  
  /**
   *    tty_insert_flip_string_flags    -       Add characters to the tty buffer
@@@ -284,8 -284,7 +285,8 @@@ int tty_insert_flip_string_flags(struc
  {
        int copied = 0;
        do {
 -              int space = tty_buffer_request_room(tty, size - copied);
 +              int goal = min(size - copied, TTY_BUFFER_PAGE);
 +              int space = tty_buffer_request_room(tty, goal);
                struct tty_buffer *tb = tty->buf.tail;
                /* If there is no space then tb may be NULL */
                if (unlikely(space == 0))
diff --combined drivers/usb/Kconfig
index 4f5bb5698f5d7b5201ae405a397223e7fb6259da,2859472996ad8e7daf73075df1b878513461b0cb..6a58cb1330c1dc016eeebd89f3ce74cc656d5c76
@@@ -21,6 -21,7 +21,7 @@@ config USB_ARCH_HAS_HC
        default y if USB_ARCH_HAS_EHCI
        default y if PCMCIA && !M32R                    # sl811_cs
        default y if ARM                                # SL-811
+       default y if BLACKFIN                           # SL-811
        default y if SUPERH                             # r8a66597-hcd
        default PCI
  
@@@ -39,6 -40,7 +40,7 @@@ config USB_ARCH_HAS_OHC
        default y if ARCH_PNX4008 && I2C
        default y if MFD_TC6393XB
        default y if ARCH_W90X900
+       default y if ARCH_DAVINCI_DA8XX
        # PPC:
        default y if STB03xxx
        default y if PPC_MPC52xx
@@@ -61,7 -63,7 +63,7 @@@ config USB_ARCH_HAS_EHC
        default y if ARCH_W90X900
        default y if ARCH_AT91SAM9G45
        default y if ARCH_MXC
 -      default y if ARCH_OMAP34XX
 +      default y if ARCH_OMAP3
        default PCI
  
  # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
index 738efd8063b5e201a1ef18b5e905de6c416634ab,0f13dedc50a19770dd2530526146624c09f2999d..b4bbf8f2c2381bb0f4de4d0042b85b2260a843d0
@@@ -557,6 -557,69 +557,69 @@@ static irqreturn_t musb_stage0_irq(stru
                handled = IRQ_HANDLED;
        }
  
+       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:
+                       /* We also come here if the cable is removed, since
+                        * this silicon doesn't report ID-no-longer-grounded.
+                        *
+                        * We depend on T(a_wait_bcon) to shut us down, and
+                        * hope users don't do anything dicey during this
+                        * undesired detour through A_WAIT_BCON.
+                        */
+                       musb_hnp_stop(musb);
+                       usb_hcd_resume_root_hub(musb_to_hcd(musb));
+                       musb_root_disconnect(musb);
+                       musb_platform_try_idle(musb, jiffies
+                                       + msecs_to_jiffies(musb->a_wait_bcon
+                                               ? : OTG_TIME_A_WAIT_BCON));
+                       break;
+ #endif
+               case OTG_STATE_B_IDLE:
+                       if (!musb->is_active)
+                               break;
+               case OTG_STATE_B_PERIPHERAL:
+                       musb_g_suspend(musb);
+                       musb->is_active = is_otg_enabled(musb)
+                                       && musb->xceiv->gadget->b_hnp_enable;
+                       if (musb->is_active) {
+ #ifdef        CONFIG_USB_MUSB_OTG
+                               musb->xceiv->state = OTG_STATE_B_WAIT_ACON;
+                               DBG(1, "HNP: Setting timer for b_ase0_brst\n");
+                               mod_timer(&musb->otg_timer, jiffies
+                                       + msecs_to_jiffies(
+                                                       OTG_TIME_B_ASE0_BRST));
+ #endif
+                       }
+                       break;
+               case OTG_STATE_A_WAIT_BCON:
+                       if (musb->a_wait_bcon != 0)
+                               musb_platform_try_idle(musb, jiffies
+                                       + msecs_to_jiffies(musb->a_wait_bcon));
+                       break;
+               case OTG_STATE_A_HOST:
+                       musb->xceiv->state = OTG_STATE_A_SUSPEND;
+                       musb->is_active = is_otg_enabled(musb)
+                                       && musb->xceiv->host->b_hnp_enable;
+                       break;
+               case OTG_STATE_B_HOST:
+                       /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */
+                       DBG(1, "REVISIT: SUSPEND as B_HOST\n");
+                       break;
+               default:
+                       /* "should not happen" */
+                       musb->is_active = 0;
+                       break;
+               }
+       }
        if (int_usb & MUSB_INTR_CONNECT) {
                struct usb_hcd *hcd = musb_to_hcd(musb);
  
@@@ -625,10 -688,61 +688,61 @@@ b_host
        }
  #endif        /* CONFIG_USB_MUSB_HDRC_HCD */
  
+       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);
+               handled = IRQ_HANDLED;
+               switch (musb->xceiv->state) {
+ #ifdef CONFIG_USB_MUSB_HDRC_HCD
+               case OTG_STATE_A_HOST:
+               case OTG_STATE_A_SUSPEND:
+                       usb_hcd_resume_root_hub(musb_to_hcd(musb));
+                       musb_root_disconnect(musb);
+                       if (musb->a_wait_bcon != 0 && is_otg_enabled(musb))
+                               musb_platform_try_idle(musb, jiffies
+                                       + msecs_to_jiffies(musb->a_wait_bcon));
+                       break;
+ #endif        /* HOST */
+ #ifdef CONFIG_USB_MUSB_OTG
+               case OTG_STATE_B_HOST:
+                       /* REVISIT this behaves for "real disconnect"
+                        * cases; make sure the other transitions from
+                        * from B_HOST act right too.  The B_HOST code
+                        * in hnp_stop() is currently not used...
+                        */
+                       musb_root_disconnect(musb);
+                       musb_to_hcd(musb)->self.is_b_host = 0;
+                       musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
+                       MUSB_DEV_MODE(musb);
+                       musb_g_disconnect(musb);
+                       break;
+               case OTG_STATE_A_PERIPHERAL:
+                       musb_hnp_stop(musb);
+                       musb_root_disconnect(musb);
+                       /* FALLTHROUGH */
+               case OTG_STATE_B_WAIT_ACON:
+                       /* FALLTHROUGH */
+ #endif        /* OTG */
+ #ifdef CONFIG_USB_GADGET_MUSB_HDRC
+               case OTG_STATE_B_PERIPHERAL:
+               case OTG_STATE_B_IDLE:
+                       musb_g_disconnect(musb);
+                       break;
+ #endif        /* GADGET */
+               default:
+                       WARNING("unhandled DISCONNECT transition (%s)\n",
+                               otg_state_string(musb));
+                       break;
+               }
+       }
        /* mentor saves a bit: bus reset and babble share the same irq.
         * only host sees babble; only peripheral sees bus reset.
         */
        if (int_usb & MUSB_INTR_RESET) {
+               handled = IRQ_HANDLED;
                if (is_host_capable() && (devctl & MUSB_DEVCTL_HM) != 0) {
                        /*
                         * Looks like non-HS BABBLE can be ignored, but
                                DBG(1, "BABBLE devctl: %02x\n", devctl);
                        else {
                                ERR("Stopping host session -- babble\n");
-                               musb_writeb(mbase, MUSB_DEVCTL, 0);
+                               musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
                        }
                } else if (is_peripheral_capable()) {
                        DBG(1, "BUS RESET as %s\n", otg_state_string(musb));
                                        otg_state_string(musb));
                        }
                }
-               handled = IRQ_HANDLED;
        }
-       schedule_work(&musb->irq_work);
-       return handled;
- }
- /*
-  * Interrupt Service Routine to record USB "global" interrupts.
-  * Since these do not happen often and signify things of
-  * paramount importance, it seems OK to check them individually;
-  * the order of the tests is specified in the manual
-  *
-  * @param musb instance pointer
-  * @param int_usb register contents
-  * @param devctl
-  * @param power
-  */
- static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
-                               u8 devctl, u8 power)
- {
-       irqreturn_t handled = IRQ_NONE;
  
  #if 0
  /* REVISIT ... this would be for multiplexing periodic endpoints, or
        }
  #endif
  
-       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);
-               handled = IRQ_HANDLED;
-               switch (musb->xceiv->state) {
- #ifdef CONFIG_USB_MUSB_HDRC_HCD
-               case OTG_STATE_A_HOST:
-               case OTG_STATE_A_SUSPEND:
-                       usb_hcd_resume_root_hub(musb_to_hcd(musb));
-                       musb_root_disconnect(musb);
-                       if (musb->a_wait_bcon != 0 && is_otg_enabled(musb))
-                               musb_platform_try_idle(musb, jiffies
-                                       + msecs_to_jiffies(musb->a_wait_bcon));
-                       break;
- #endif        /* HOST */
- #ifdef CONFIG_USB_MUSB_OTG
-               case OTG_STATE_B_HOST:
-                       /* REVISIT this behaves for "real disconnect"
-                        * cases; make sure the other transitions from
-                        * from B_HOST act right too.  The B_HOST code
-                        * in hnp_stop() is currently not used...
-                        */
-                       musb_root_disconnect(musb);
-                       musb_to_hcd(musb)->self.is_b_host = 0;
-                       musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
-                       MUSB_DEV_MODE(musb);
-                       musb_g_disconnect(musb);
-                       break;
-               case OTG_STATE_A_PERIPHERAL:
-                       musb_hnp_stop(musb);
-                       musb_root_disconnect(musb);
-                       /* FALLTHROUGH */
-               case OTG_STATE_B_WAIT_ACON:
-                       /* FALLTHROUGH */
- #endif        /* OTG */
- #ifdef CONFIG_USB_GADGET_MUSB_HDRC
-               case OTG_STATE_B_PERIPHERAL:
-               case OTG_STATE_B_IDLE:
-                       musb_g_disconnect(musb);
-                       break;
- #endif        /* GADGET */
-               default:
-                       WARNING("unhandled DISCONNECT transition (%s)\n",
-                               otg_state_string(musb));
-                       break;
-               }
-               schedule_work(&musb->irq_work);
-       }
-       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:
-                       /* We also come here if the cable is removed, since
-                        * this silicon doesn't report ID-no-longer-grounded.
-                        *
-                        * We depend on T(a_wait_bcon) to shut us down, and
-                        * hope users don't do anything dicey during this
-                        * undesired detour through A_WAIT_BCON.
-                        */
-                       musb_hnp_stop(musb);
-                       usb_hcd_resume_root_hub(musb_to_hcd(musb));
-                       musb_root_disconnect(musb);
-                       musb_platform_try_idle(musb, jiffies
-                                       + msecs_to_jiffies(musb->a_wait_bcon
-                                               ? : OTG_TIME_A_WAIT_BCON));
-                       break;
- #endif
-               case OTG_STATE_B_PERIPHERAL:
-                       musb_g_suspend(musb);
-                       musb->is_active = is_otg_enabled(musb)
-                                       && musb->xceiv->gadget->b_hnp_enable;
-                       if (musb->is_active) {
- #ifdef        CONFIG_USB_MUSB_OTG
-                               musb->xceiv->state = OTG_STATE_B_WAIT_ACON;
-                               DBG(1, "HNP: Setting timer for b_ase0_brst\n");
-                               mod_timer(&musb->otg_timer, jiffies
-                                       + msecs_to_jiffies(
-                                                       OTG_TIME_B_ASE0_BRST));
- #endif
-                       }
-                       break;
-               case OTG_STATE_A_WAIT_BCON:
-                       if (musb->a_wait_bcon != 0)
-                               musb_platform_try_idle(musb, jiffies
-                                       + msecs_to_jiffies(musb->a_wait_bcon));
-                       break;
-               case OTG_STATE_A_HOST:
-                       musb->xceiv->state = OTG_STATE_A_SUSPEND;
-                       musb->is_active = is_otg_enabled(musb)
-                                       && musb->xceiv->host->b_hnp_enable;
-                       break;
-               case OTG_STATE_B_HOST:
-                       /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */
-                       DBG(1, "REVISIT: SUSPEND as B_HOST\n");
-                       break;
-               default:
-                       /* "should not happen" */
-                       musb->is_active = 0;
-                       break;
-               }
-               schedule_work(&musb->irq_work);
-       }
+       schedule_work(&musb->irq_work);
  
        return handled;
  }
@@@ -1000,7 -982,7 +982,7 @@@ static void musb_shutdown(struct platfo
   * more than selecting one of a bunch of predefined configurations.
   */
  #if defined(CONFIG_USB_TUSB6010) || \
 -      defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
 +      defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
  static ushort __initdata fifo_mode = 4;
  #else
  static ushort __initdata fifo_mode = 2;
@@@ -1095,6 -1077,36 +1077,36 @@@ static struct fifo_cfg __initdata mode_
  { .hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024, },
  };
  
+ /* mode 5 - fits in 8KB */
+ static struct fifo_cfg __initdata mode_5_cfg[] = {
+ { .hw_ep_num =  1, .style = FIFO_TX,   .maxpacket = 512, },
+ { .hw_ep_num =  1, .style = FIFO_RX,   .maxpacket = 512, },
+ { .hw_ep_num =  2, .style = FIFO_TX,   .maxpacket = 512, },
+ { .hw_ep_num =  2, .style = FIFO_RX,   .maxpacket = 512, },
+ { .hw_ep_num =  3, .style = FIFO_TX,   .maxpacket = 512, },
+ { .hw_ep_num =  3, .style = FIFO_RX,   .maxpacket = 512, },
+ { .hw_ep_num =  4, .style = FIFO_TX,   .maxpacket = 512, },
+ { .hw_ep_num =  4, .style = FIFO_RX,   .maxpacket = 512, },
+ { .hw_ep_num =  5, .style = FIFO_TX,   .maxpacket = 512, },
+ { .hw_ep_num =  5, .style = FIFO_RX,   .maxpacket = 512, },
+ { .hw_ep_num =  6, .style = FIFO_TX,   .maxpacket = 32, },
+ { .hw_ep_num =  6, .style = FIFO_RX,   .maxpacket = 32, },
+ { .hw_ep_num =  7, .style = FIFO_TX,   .maxpacket = 32, },
+ { .hw_ep_num =  7, .style = FIFO_RX,   .maxpacket = 32, },
+ { .hw_ep_num =  8, .style = FIFO_TX,   .maxpacket = 32, },
+ { .hw_ep_num =  8, .style = FIFO_RX,   .maxpacket = 32, },
+ { .hw_ep_num =  9, .style = FIFO_TX,   .maxpacket = 32, },
+ { .hw_ep_num =  9, .style = FIFO_RX,   .maxpacket = 32, },
+ { .hw_ep_num = 10, .style = FIFO_TX,   .maxpacket = 32, },
+ { .hw_ep_num = 10, .style = FIFO_RX,   .maxpacket = 32, },
+ { .hw_ep_num = 11, .style = FIFO_TX,   .maxpacket = 32, },
+ { .hw_ep_num = 11, .style = FIFO_RX,   .maxpacket = 32, },
+ { .hw_ep_num = 12, .style = FIFO_TX,   .maxpacket = 32, },
+ { .hw_ep_num = 12, .style = FIFO_RX,   .maxpacket = 32, },
+ { .hw_ep_num = 13, .style = FIFO_RXTX, .maxpacket = 512, },
+ { .hw_ep_num = 14, .style = FIFO_RXTX, .maxpacket = 1024, },
+ { .hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024, },
+ };
  
  /*
   * configure a fifo; for non-shared endpoints, this may be called
@@@ -1210,6 -1222,10 +1222,10 @@@ static int __init ep_config_from_table(
                cfg = mode_4_cfg;
                n = ARRAY_SIZE(mode_4_cfg);
                break;
+       case 5:
+               cfg = mode_5_cfg;
+               n = ARRAY_SIZE(mode_5_cfg);
+               break;
        }
  
        printk(KERN_DEBUG "%s: setup fifo_mode %d\n",
@@@ -1314,9 -1330,6 +1330,6 @@@ enum { MUSB_CONTROLLER_MHDRC, MUSB_CONT
   */
  static int __init musb_core_init(u16 musb_type, struct musb *musb)
  {
- #ifdef MUSB_AHB_ID
-       u32 data;
- #endif
        u8 reg;
        char *type;
        char aInfo[90], aRevision[32], aDate[12];
        reg = musb_read_configdata(mbase);
  
        strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8");
-       if (reg & MUSB_CONFIGDATA_DYNFIFO)
+       if (reg & MUSB_CONFIGDATA_DYNFIFO) {
                strcat(aInfo, ", dyn FIFOs");
+               musb->dyn_fifo = true;
+       }
        if (reg & MUSB_CONFIGDATA_MPRXE) {
                strcat(aInfo, ", bulk combine");
- #ifdef C_MP_RX
                musb->bulk_combine = true;
- #else
-               strcat(aInfo, " (X)");          /* no driver support */
- #endif
        }
        if (reg & MUSB_CONFIGDATA_MPTXE) {
                strcat(aInfo, ", bulk split");
- #ifdef C_MP_TX
                musb->bulk_split = true;
- #else
-               strcat(aInfo, " (X)");          /* no driver support */
- #endif
        }
        if (reg & MUSB_CONFIGDATA_HBRXE) {
                strcat(aInfo, ", HB-ISO Rx");
        printk(KERN_DEBUG "%s: ConfigData=0x%02x (%s)\n",
                        musb_driver_name, reg, aInfo);
  
- #ifdef MUSB_AHB_ID
-       data = musb_readl(mbase, 0x404);
-       sprintf(aDate, "%04d-%02x-%02x", (data & 0xffff),
-               (data >> 16) & 0xff, (data >> 24) & 0xff);
-       /* FIXME ID2 and ID3 are unused */
-       data = musb_readl(mbase, 0x408);
-       printk(KERN_DEBUG "ID2=%lx\n", (long unsigned)data);
-       data = musb_readl(mbase, 0x40c);
-       printk(KERN_DEBUG "ID3=%lx\n", (long unsigned)data);
-       reg = musb_readb(mbase, 0x400);
-       musb_type = ('M' == reg) ? MUSB_CONTROLLER_MHDRC : MUSB_CONTROLLER_HDRC;
- #else
        aDate[0] = 0;
- #endif
        if (MUSB_CONTROLLER_MHDRC == musb_type) {
                musb->is_multipoint = 1;
                type = "M";
        musb->nr_endpoints = 1;
        musb->epmask = 1;
  
-       if (reg & MUSB_CONFIGDATA_DYNFIFO) {
-               if (musb->config->dyn_fifo)
-                       status = ep_config_from_table(musb);
-               else {
-                       ERR("reconfigure software for Dynamic FIFOs\n");
-                       status = -ENODEV;
-               }
-       } else {
-               if (!musb->config->dyn_fifo)
-                       status = ep_config_from_hw(musb);
-               else {
-                       ERR("reconfigure software for static FIFOs\n");
-                       return -ENODEV;
-               }
-       }
+       if (musb->dyn_fifo)
+               status = ep_config_from_table(musb);
+       else
+               status = ep_config_from_hw(musb);
  
        if (status < 0)
                return status;
@@@ -1587,11 -1570,6 +1570,6 @@@ irqreturn_t musb_interrupt(struct musb 
                ep_num++;
        }
  
-       /* finish handling "global" interrupts after handling fifos */
-       if (musb->int_usb)
-               retval |= musb_stage2_irq(musb,
-                               musb->int_usb, devctl, power);
        return retval;
  }
  
@@@ -1696,7 -1674,7 +1674,7 @@@ musb_vbus_store(struct device *dev, str
        unsigned long   val;
  
        if (sscanf(buf, "%lu", &val) < 1) {
-               printk(KERN_ERR "Invalid VBUS timeout ms value\n");
+               dev_err(dev, "Invalid VBUS timeout ms value\n");
                return -EINVAL;
        }
  
@@@ -1746,7 -1724,7 +1724,7 @@@ musb_srp_store(struct device *dev, stru
  
        if (sscanf(buf, "%hu", &srp) != 1
                        || (srp != 1)) {
-               printk(KERN_ERR "SRP: Value must be 1\n");
+               dev_err(dev, "SRP: Value must be 1\n");
                return -EINVAL;
        }
  
@@@ -1759,6 -1737,19 +1737,19 @@@ static DEVICE_ATTR(srp, 0644, NULL, mus
  
  #endif /* CONFIG_USB_GADGET_MUSB_HDRC */
  
+ static struct attribute *musb_attributes[] = {
+       &dev_attr_mode.attr,
+       &dev_attr_vbus.attr,
+ #ifdef CONFIG_USB_GADGET_MUSB_HDRC
+       &dev_attr_srp.attr,
+ #endif
+       NULL
+ };
+ static const struct attribute_group musb_attr_group = {
+       .attrs = musb_attributes,
+ };
  #endif        /* sysfs */
  
  /* Only used to provide driver mode change events */
@@@ -1833,11 -1824,7 +1824,7 @@@ static void musb_free(struct musb *musb
         */
  
  #ifdef CONFIG_SYSFS
-       device_remove_file(musb->controller, &dev_attr_mode);
-       device_remove_file(musb->controller, &dev_attr_vbus);
- #ifdef CONFIG_USB_GADGET_MUSB_HDRC
-       device_remove_file(musb->controller, &dev_attr_srp);
- #endif
+       sysfs_remove_group(&musb->controller->kobj, &musb_attr_group);
  #endif
  
  #ifdef CONFIG_USB_GADGET_MUSB_HDRC
@@@ -2017,22 -2004,10 +2004,10 @@@ bad_config
                musb->irq_wake = 0;
        }
  
-       pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n",
-                       musb_driver_name,
-                       ({char *s;
-                       switch (musb->board_mode) {
-                       case MUSB_HOST:         s = "Host"; break;
-                       case MUSB_PERIPHERAL:   s = "Peripheral"; break;
-                       default:                s = "OTG"; break;
-                       }; s; }),
-                       ctrl,
-                       (is_dma_capable() && musb->dma_controller)
-                               ? "DMA" : "PIO",
-                       musb->nIrq);
        /* host side needs more setup */
        if (is_host_enabled(musb)) {
                struct usb_hcd  *hcd = musb_to_hcd(musb);
+               u8 busctl;
  
                otg_set_host(musb->xceiv, &hcd->self);
  
                        hcd->self.otg_port = 1;
                musb->xceiv->host = &hcd->self;
                hcd->power_budget = 2 * (plat->power ? : 250);
+               /* program PHY to use external vBus if required */
+               if (plat->extvbus) {
+                       busctl = musb_readb(musb->mregs, MUSB_ULPI_BUSCONTROL);
+                       busctl |= MUSB_ULPI_USE_EXTVBUS;
+                       musb_writeb(musb->mregs, MUSB_ULPI_BUSCONTROL, busctl);
+               }
        }
  
        /* For the host-only role, we can activate right away.
        }
  
  #ifdef CONFIG_SYSFS
-       status = device_create_file(dev, &dev_attr_mode);
-       status = device_create_file(dev, &dev_attr_vbus);
- #ifdef CONFIG_USB_GADGET_MUSB_HDRC
-       status = device_create_file(dev, &dev_attr_srp);
- #endif /* CONFIG_USB_GADGET_MUSB_HDRC */
-       status = 0;
+       status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group);
  #endif
        if (status)
                goto fail2;
  
+       dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
+                       ({char *s;
+                        switch (musb->board_mode) {
+                        case MUSB_HOST:                s = "Host"; break;
+                        case MUSB_PERIPHERAL:  s = "Peripheral"; break;
+                        default:               s = "OTG"; break;
+                        }; s; }),
+                       ctrl,
+                       (is_dma_capable() && musb->dma_controller)
+                       ? "DMA" : "PIO",
+                       musb->nIrq);
        return 0;
  
  fail2:
- #ifdef CONFIG_SYSFS
-       device_remove_file(musb->controller, &dev_attr_mode);
-       device_remove_file(musb->controller, &dev_attr_vbus);
- #ifdef CONFIG_USB_GADGET_MUSB_HDRC
-       device_remove_file(musb->controller, &dev_attr_srp);
- #endif
- #endif
        musb_platform_exit(musb);
  fail:
        dev_err(musb->controller,
@@@ -2127,6 -2109,7 +2109,7 @@@ static int __init musb_probe(struct pla
  {
        struct device   *dev = &pdev->dev;
        int             irq = platform_get_irq(pdev, 0);
+       int             status;
        struct resource *iomem;
        void __iomem    *base;
  
        if (!iomem || irq == 0)
                return -ENODEV;
  
-       base = ioremap(iomem->start, iomem->end - iomem->start + 1);
+       base = ioremap(iomem->start, resource_size(iomem));
        if (!base) {
                dev_err(dev, "ioremap failed\n");
                return -ENOMEM;
        /* clobbered by use_dma=n */
        orig_dma_mask = dev->dma_mask;
  #endif
-       return musb_init_controller(dev, irq, base);
+       status = musb_init_controller(dev, irq, base);
+       if (status < 0)
+               iounmap(base);
+       return status;
  }
  
  static int __exit musb_remove(struct platform_device *pdev)
  
  #ifdef        CONFIG_PM
  
+ static struct musb_context_registers musb_context;
+ void musb_save_context(struct musb *musb)
+ {
+       int i;
+       void __iomem *musb_base = musb->mregs;
+       if (is_host_enabled(musb)) {
+               musb_context.frame = musb_readw(musb_base, MUSB_FRAME);
+               musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE);
+       }
+       musb_context.power = musb_readb(musb_base, MUSB_POWER);
+       musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE);
+       musb_context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE);
+       musb_context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE);
+       musb_context.index = musb_readb(musb_base, MUSB_INDEX);
+       musb_context.devctl = musb_readb(musb_base, MUSB_DEVCTL);
+       for (i = 0; i < MUSB_C_NUM_EPS; ++i) {
+               musb_writeb(musb_base, MUSB_INDEX, i);
+               musb_context.index_regs[i].txmaxp =
+                       musb_readw(musb_base, 0x10 + MUSB_TXMAXP);
+               musb_context.index_regs[i].txcsr =
+                       musb_readw(musb_base, 0x10 + MUSB_TXCSR);
+               musb_context.index_regs[i].rxmaxp =
+                       musb_readw(musb_base, 0x10 + MUSB_RXMAXP);
+               musb_context.index_regs[i].rxcsr =
+                       musb_readw(musb_base, 0x10 + MUSB_RXCSR);
+               if (musb->dyn_fifo) {
+                       musb_context.index_regs[i].txfifoadd =
+                                       musb_read_txfifoadd(musb_base);
+                       musb_context.index_regs[i].rxfifoadd =
+                                       musb_read_rxfifoadd(musb_base);
+                       musb_context.index_regs[i].txfifosz =
+                                       musb_read_txfifosz(musb_base);
+                       musb_context.index_regs[i].rxfifosz =
+                                       musb_read_rxfifosz(musb_base);
+               }
+               if (is_host_enabled(musb)) {
+                       musb_context.index_regs[i].txtype =
+                               musb_readb(musb_base, 0x10 + MUSB_TXTYPE);
+                       musb_context.index_regs[i].txinterval =
+                               musb_readb(musb_base, 0x10 + MUSB_TXINTERVAL);
+                       musb_context.index_regs[i].rxtype =
+                               musb_readb(musb_base, 0x10 + MUSB_RXTYPE);
+                       musb_context.index_regs[i].rxinterval =
+                               musb_readb(musb_base, 0x10 + MUSB_RXINTERVAL);
+                       musb_context.index_regs[i].txfunaddr =
+                               musb_read_txfunaddr(musb_base, i);
+                       musb_context.index_regs[i].txhubaddr =
+                               musb_read_txhubaddr(musb_base, i);
+                       musb_context.index_regs[i].txhubport =
+                               musb_read_txhubport(musb_base, i);
+                       musb_context.index_regs[i].rxfunaddr =
+                               musb_read_rxfunaddr(musb_base, i);
+                       musb_context.index_regs[i].rxhubaddr =
+                               musb_read_rxhubaddr(musb_base, i);
+                       musb_context.index_regs[i].rxhubport =
+                               musb_read_rxhubport(musb_base, i);
+               }
+       }
+       musb_writeb(musb_base, MUSB_INDEX, musb_context.index);
+       musb_platform_save_context(musb, &musb_context);
+ }
+ void musb_restore_context(struct musb *musb)
+ {
+       int i;
+       void __iomem *musb_base = musb->mregs;
+       void __iomem *ep_target_regs;
+       musb_platform_restore_context(musb, &musb_context);
+       if (is_host_enabled(musb)) {
+               musb_writew(musb_base, MUSB_FRAME, musb_context.frame);
+               musb_writeb(musb_base, MUSB_TESTMODE, musb_context.testmode);
+       }
+       musb_writeb(musb_base, MUSB_POWER, musb_context.power);
+       musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe);
+       musb_writew(musb_base, MUSB_INTRRXE, musb_context.intrrxe);
+       musb_writeb(musb_base, MUSB_INTRUSBE, musb_context.intrusbe);
+       musb_writeb(musb_base, MUSB_DEVCTL, musb_context.devctl);
+       for (i = 0; i < MUSB_C_NUM_EPS; ++i) {
+               musb_writeb(musb_base, MUSB_INDEX, i);
+               musb_writew(musb_base, 0x10 + MUSB_TXMAXP,
+                       musb_context.index_regs[i].txmaxp);
+               musb_writew(musb_base, 0x10 + MUSB_TXCSR,
+                       musb_context.index_regs[i].txcsr);
+               musb_writew(musb_base, 0x10 + MUSB_RXMAXP,
+                       musb_context.index_regs[i].rxmaxp);
+               musb_writew(musb_base, 0x10 + MUSB_RXCSR,
+                       musb_context.index_regs[i].rxcsr);
+               if (musb->dyn_fifo) {
+                       musb_write_txfifosz(musb_base,
+                               musb_context.index_regs[i].txfifosz);
+                       musb_write_rxfifosz(musb_base,
+                               musb_context.index_regs[i].rxfifosz);
+                       musb_write_txfifoadd(musb_base,
+                               musb_context.index_regs[i].txfifoadd);
+                       musb_write_rxfifoadd(musb_base,
+                               musb_context.index_regs[i].rxfifoadd);
+               }
+               if (is_host_enabled(musb)) {
+                       musb_writeb(musb_base, 0x10 + MUSB_TXTYPE,
+                               musb_context.index_regs[i].txtype);
+                       musb_writeb(musb_base, 0x10 + MUSB_TXINTERVAL,
+                               musb_context.index_regs[i].txinterval);
+                       musb_writeb(musb_base, 0x10 + MUSB_RXTYPE,
+                               musb_context.index_regs[i].rxtype);
+                       musb_writeb(musb_base, 0x10 + MUSB_RXINTERVAL,
+                       musb_context.index_regs[i].rxinterval);
+                       musb_write_txfunaddr(musb_base, i,
+                               musb_context.index_regs[i].txfunaddr);
+                       musb_write_txhubaddr(musb_base, i,
+                               musb_context.index_regs[i].txhubaddr);
+                       musb_write_txhubport(musb_base, i,
+                               musb_context.index_regs[i].txhubport);
+                       ep_target_regs =
+                               musb_read_target_reg_base(i, musb_base);
+                       musb_write_rxfunaddr(ep_target_regs,
+                               musb_context.index_regs[i].rxfunaddr);
+                       musb_write_rxhubaddr(ep_target_regs,
+                               musb_context.index_regs[i].rxhubaddr);
+                       musb_write_rxhubport(ep_target_regs,
+                               musb_context.index_regs[i].rxhubport);
+               }
+       }
+       musb_writeb(musb_base, MUSB_INDEX, musb_context.index);
+ }
  static int musb_suspend(struct device *dev)
  {
        struct platform_device *pdev = to_platform_device(dev);
                 */
        }
  
+       musb_save_context(musb);
        if (musb->set_clock)
                musb->set_clock(musb->clock, 0);
        else
@@@ -2215,6 -2347,8 +2347,8 @@@ static int musb_resume_noirq(struct dev
        else
                clk_enable(musb->clock);
  
+       musb_restore_context(musb);
        /* for static cmos like DaVinci, register values were preserved
         * unless for some reason the whole soc powered down or the USB
         * module got reset through the PSC (vs just being disabled).
index 5514c7ee85bd678917b13c0820ff1d05538541bd,17e7115493ffd99d11d1602d4a977b58646c2b36..d849fb81c131cb6cae9bcb3f9d7ce58020219c46
@@@ -52,6 -52,15 +52,15 @@@ struct musb
  struct musb_hw_ep;
  struct musb_ep;
  
+ /* Helper defines for struct musb->hwvers */
+ #define MUSB_HWVERS_MAJOR(x)  ((x >> 10) & 0x1f)
+ #define MUSB_HWVERS_MINOR(x)  (x & 0x3ff)
+ #define MUSB_HWVERS_RC                0x8000
+ #define MUSB_HWVERS_1300      0x52C
+ #define MUSB_HWVERS_1400      0x590
+ #define MUSB_HWVERS_1800      0x720
+ #define MUSB_HWVERS_1900      0x784
+ #define MUSB_HWVERS_2000      0x800
  
  #include "musb_debug.h"
  #include "musb_dma.h"
@@@ -322,13 -331,6 +331,6 @@@ struct musb 
        struct clk              *clock;
        irqreturn_t             (*isr)(int, void *);
        struct work_struct      irq_work;
- #define MUSB_HWVERS_MAJOR(x)  ((x >> 10) & 0x1f)
- #define MUSB_HWVERS_MINOR(x)  (x & 0x3ff)
- #define MUSB_HWVERS_RC                0x8000
- #define MUSB_HWVERS_1300      0x52C
- #define MUSB_HWVERS_1400      0x590
- #define MUSB_HWVERS_1800      0x720
- #define MUSB_HWVERS_2000      0x800
        u16                     hwvers;
  
  /* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
  
        unsigned                hb_iso_rx:1;    /* high bandwidth iso rx? */
        unsigned                hb_iso_tx:1;    /* high bandwidth iso tx? */
+       unsigned                dyn_fifo:1;     /* dynamic FIFO supported? */
  
- #ifdef C_MP_TX
-       unsigned bulk_split:1;
+       unsigned                bulk_split:1;
  #define       can_bulk_split(musb,type) \
-               (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_split)
- #else
- #define       can_bulk_split(musb, type)      0
- #endif
+       (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_split)
  
- #ifdef C_MP_RX
-       unsigned bulk_combine:1;
+       unsigned                bulk_combine:1;
  #define       can_bulk_combine(musb,type) \
-               (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_combine)
- #else
- #define       can_bulk_combine(musb, type)    0
- #endif
+       (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_combine)
  
  #ifdef CONFIG_USB_GADGET_MUSB_HDRC
        /* is_suspended means USB B_PERIPHERAL suspend */
  #endif
  };
  
+ #ifdef CONFIG_PM
+ struct musb_csr_regs {
+       /* FIFO registers */
+       u16 txmaxp, txcsr, rxmaxp, rxcsr;
+       u16 rxfifoadd, txfifoadd;
+       u8 txtype, txinterval, rxtype, rxinterval;
+       u8 rxfifosz, txfifosz;
+       u8 txfunaddr, txhubaddr, txhubport;
+       u8 rxfunaddr, rxhubaddr, rxhubport;
+ };
+ struct musb_context_registers {
+ #if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430)
+       u32 otg_sysconfig, otg_forcestandby;
+ #endif
+       u8 power;
+       u16 intrtxe, intrrxe;
+       u8 intrusbe;
+       u16 frame;
+       u8 index, testmode;
+       u8 devctl, misc;
+       struct musb_csr_regs index_regs[MUSB_C_NUM_EPS];
+ };
+ #if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430)
+ extern void musb_platform_save_context(struct musb *musb,
+               struct musb_context_registers *musb_context);
+ extern void musb_platform_restore_context(struct musb *musb,
+               struct musb_context_registers *musb_context);
+ #else
+ #define musb_platform_save_context(m, x)      do {} while (0)
+ #define musb_platform_restore_context(m, x)   do {} while (0)
+ #endif
+ #endif
  static inline void musb_set_vbus(struct musb *musb, int is_on)
  {
        musb->board_set_vbus(musb, is_on);
@@@ -562,7 -596,7 +596,7 @@@ extern void musb_hnp_stop(struct musb *
  extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode);
  
  #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \
 -      defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
 +      defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
  extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout);
  #else
  #define musb_platform_try_idle(x, y)          do {} while (0)
index 84f08e968e0b3e250562e4401dd801accc9e50cb,4efde03fa93b265695b62304089ccd8dc2438e7b..185fe9a7d4e05f277bd1293343aa0f80394d8835
@@@ -125,7 -125,7 +125,7 @@@ struct keyspan_pda_private 
  #define ENTREGRA_VENDOR_ID            0x1645
  #define ENTREGRA_FAKE_ID              0x8093
  
- static struct usb_device_id id_table_combined [] = {
+ static const struct usb_device_id id_table_combined[] = {
  #ifdef KEYSPAN
        { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
  #endif
@@@ -147,20 -147,20 +147,20 @@@ static struct usb_driver keyspan_pda_dr
        .no_dynamic_id =        1,
  };
  
- static struct usb_device_id id_table_std [] = {
+ static const struct usb_device_id id_table_std[] = {
        { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
        { }                                             /* Terminating entry */
  };
  
  #ifdef KEYSPAN
- static struct usb_device_id id_table_fake [] = {
+ static const struct usb_device_id id_table_fake[] = {
        { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
        { }                                             /* Terminating entry */
  };
  #endif
  
  #ifdef XIRCOM
- static struct usb_device_id id_table_fake_xircom [] = {
+ static const struct usb_device_id id_table_fake_xircom[] = {
        { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
        { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
        { }
@@@ -429,13 -429,20 +429,20 @@@ static int keyspan_pda_get_modem_info(s
                                      unsigned char *value)
  {
        int rc;
-       unsigned char data;
+       u8 *data;
+       data = kmalloc(1, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
        rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                             3, /* get pins */
                             USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN,
-                            0, 0, &data, 1, 2000);
+                            0, 0, data, 1, 2000);
        if (rc >= 0)
-               *value = data;
+               *value = *data;
+       kfree(data);
        return rc;
  }
  
@@@ -543,7 -550,14 +550,14 @@@ static int keyspan_pda_write(struct tty
           device how much room it really has.  This is done only on
           scheduler time, since usb_control_msg() sleeps. */
        if (count > priv->tx_room && !in_interrupt()) {
-               unsigned char room;
+               u8 *room;
+               room = kmalloc(1, GFP_KERNEL);
+               if (!room) {
+                       rc = -ENOMEM;
+                       goto exit;
+               }
                rc = usb_control_msg(serial->dev,
                                     usb_rcvctrlpipe(serial->dev, 0),
                                     6, /* write_room */
                                     | USB_DIR_IN,
                                     0, /* value: 0 means "remaining room" */
                                     0, /* index */
-                                    &room,
+                                    room,
                                     1,
                                     2000);
+               if (rc > 0) {
+                       dbg(" roomquery says %d", *room);
+                       priv->tx_room = *room;
+               }
+               kfree(room);
                if (rc < 0) {
                        dbg(" roomquery failed");
                        goto exit;
                        rc = -EIO; /* device didn't return any data */
                        goto exit;
                }
-               dbg(" roomquery says %d", room);
-               priv->tx_room = room;
        }
        if (count > priv->tx_room) {
                /* we're about to completely fill the Tx buffer, so
@@@ -684,18 -701,22 +701,22 @@@ static int keyspan_pda_open(struct tty_
                                        struct usb_serial_port *port)
  {
        struct usb_serial *serial = port->serial;
-       unsigned char room;
+       u8 *room;
        int rc = 0;
        struct keyspan_pda_private *priv;
  
        /* find out how much room is in the Tx ring */
+       room = kmalloc(1, GFP_KERNEL);
+       if (!room)
+               return -ENOMEM;
        rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                             6, /* write_room */
                             USB_TYPE_VENDOR | USB_RECIP_INTERFACE
                             | USB_DIR_IN,
                             0, /* value */
                             0, /* index */
-                            &room,
+                            room,
                             1,
                             2000);
        if (rc < 0) {
                goto error;
        }
        priv = usb_get_serial_port_data(port);
-       priv->tx_room = room;
-       priv->tx_throttled = room ? 0 : 1;
+       priv->tx_room = *room;
+       priv->tx_throttled = *room ? 0 : 1;
  
        /*Start reading from the device*/
        port->interrupt_in_urb->dev = serial->dev;
                dbg("%s - usb_submit_urb(read int) failed", __func__);
                goto error;
        }
  error:
+       kfree(room);
        return rc;
  }
  static void keyspan_pda_close(struct usb_serial_port *port)
@@@ -789,13 -810,6 +810,13 @@@ static int keyspan_pda_fake_startup(str
        return 1;
  }
  
 +#ifdef KEYSPAN
 +MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw");
 +#endif
 +#ifdef XIRCOM
 +MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw");
 +#endif
 +
  static int keyspan_pda_startup(struct usb_serial *serial)
  {
  
diff --combined include/linux/usb/musb.h
index 5dc2f227a0f1591bc5a8dd1165a3218da2901a62,8e0f2bc8d8c9e8290edbe61da97930bc7ab13706..7acef0234c0ec800c0beef24fe9cc98ce43beafc
@@@ -30,26 -30,26 +30,26 @@@ struct musb_hdrc_eps_bits 
  struct musb_hdrc_config {
        /* MUSB configuration-specific details */
        unsigned        multipoint:1;   /* multipoint device */
-       unsigned        dyn_fifo:1;     /* supports dynamic fifo sizing */
-       unsigned        soft_con:1;     /* soft connect required */
-       unsigned        utm_16:1;       /* utm data witdh is 16 bits */
+       unsigned        dyn_fifo:1 __deprecated; /* supports dynamic fifo sizing */
+       unsigned        soft_con:1 __deprecated; /* soft connect required */
+       unsigned        utm_16:1 __deprecated; /* utm data witdh is 16 bits */
        unsigned        big_endian:1;   /* true if CPU uses big-endian */
        unsigned        mult_bulk_tx:1; /* Tx ep required for multbulk pkts */
        unsigned        mult_bulk_rx:1; /* Rx ep required for multbulk pkts */
        unsigned        high_iso_tx:1;  /* Tx ep required for HB iso */
        unsigned        high_iso_rx:1;  /* Rx ep required for HD iso */
-       unsigned        dma:1;          /* supports DMA */
-       unsigned        vendor_req:1;   /* vendor registers required */
+       unsigned        dma:1 __deprecated; /* supports DMA */
+       unsigned        vendor_req:1 __deprecated; /* vendor registers required */
  
        u8              num_eps;        /* number of endpoints _with_ ep0 */
-       u8              dma_channels;   /* number of dma channels */
+       u8              dma_channels __deprecated; /* number of dma channels */
        u8              dyn_fifo_size;  /* dynamic size in bytes */
-       u8              vendor_ctrl;    /* vendor control reg width */
-       u8              vendor_stat;    /* vendor status reg witdh */
-       u8              dma_req_chan;   /* bitmask for required dma channels */
+       u8              vendor_ctrl __deprecated; /* vendor control reg width */
+       u8              vendor_stat __deprecated; /* vendor status reg witdh */
+       u8              dma_req_chan __deprecated; /* bitmask for required dma channels */
        u8              ram_bits;       /* ram address size */
  
-       struct musb_hdrc_eps_bits *eps_bits;
+       struct musb_hdrc_eps_bits *eps_bits __deprecated;
  #ifdef CONFIG_BLACKFIN
          /* A GPIO controlling VRSEL in Blackfin */
          unsigned int    gpio_vrsel;
@@@ -76,6 -76,9 +76,9 @@@ struct musb_hdrc_platform_data 
        /* (HOST or OTG) msec/2 after VBUS on till power good */
        u8              potpgt;
  
+       /* (HOST or OTG) program PHY for external Vbus */
+       unsigned        extvbus:1;
        /* Power the device on or off */
        int             (*set_power)(int state);
  
@@@ -84,9 -87,6 +87,9 @@@
  
        /* MUSB configuration-specific details */
        struct musb_hdrc_config *config;
 +
 +      /* Architecture specific board data     */
 +      void            *board_data;
  };
  
  
diff --combined include/linux/usb/otg.h
index fef0972c814672ec04f8b3d60b269a2d9ad8f46b,6c0b676b27d83e5ca352aa0fb46ca7884eabbc6a..f8302d036a7674e33109bf8fce16d67325d2d17a
@@@ -9,6 -9,8 +9,8 @@@
  #ifndef __LINUX_USB_OTG_H
  #define __LINUX_USB_OTG_H
  
+ #include <linux/notifier.h>
  /* OTG defines lots of enumeration states before device reset */
  enum usb_otg_state {
        OTG_STATE_UNDEFINED = 0,
        OTG_STATE_A_VBUS_ERR,
  };
  
+ enum usb_xceiv_events {
+       USB_EVENT_NONE,         /* no events or cable disconnected */
+       USB_EVENT_VBUS,         /* vbus valid event */
+       USB_EVENT_ID,           /* id was grounded */
+       USB_EVENT_CHARGER,      /* usb dedicated charger */
+       USB_EVENT_ENUMERATED,   /* gadget driver enumerated */
+ };
  #define USB_OTG_PULLUP_ID             (1 << 0)
  #define USB_OTG_PULLDOWN_DP           (1 << 1)
  #define USB_OTG_PULLDOWN_DM           (1 << 2)
@@@ -70,6 -80,9 +80,9 @@@ struct otg_transceiver 
        struct otg_io_access_ops        *io_ops;
        void __iomem                    *io_priv;
  
+       /* for notification of usb_xceiv_events */
+       struct blocking_notifier_head   notifier;
        /* to pass extra port status to the root hub */
        u16                     port_status;
        u16                     port_change;
  /* for board-specific init logic */
  extern int otg_set_transceiver(struct otg_transceiver *);
  
 +#if defined(CONFIG_NOP_USB_XCEIV) || defined(CONFIG_NOP_USB_XCEIV_MODULE)
  /* sometimes transceivers are accessed only through e.g. ULPI */
  extern void usb_nop_xceiv_register(void);
  extern void usb_nop_xceiv_unregister(void);
 +#else
 +static inline void usb_nop_xceiv_register(void)
 +{
 +}
 +
 +static inline void usb_nop_xceiv_unregister(void)
 +{
 +}
 +#endif
  
  /* helpers for direct access thru low-level io interface */
  static inline int otg_io_read(struct otg_transceiver *otg, u32 reg)
@@@ -213,6 -216,18 +226,18 @@@ otg_start_srp(struct otg_transceiver *o
        return otg->start_srp(otg);
  }
  
+ /* notifiers */
+ static inline int
+ otg_register_notifier(struct otg_transceiver *otg, struct notifier_block *nb)
+ {
+       return blocking_notifier_chain_register(&otg->notifier, nb);
+ }
+ static inline void
+ otg_unregister_notifier(struct otg_transceiver *otg, struct notifier_block *nb)
+ {
+       blocking_notifier_chain_unregister(&otg->notifier, nb);
+ }
  
  /* for OTG controller drivers (and maybe other stuff) */
  extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num);