Merge USB 4.20-rc8 mergepoint into usb-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 21 Dec 2018 15:46:08 +0000 (16:46 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 21 Dec 2018 15:46:08 +0000 (16:46 +0100)
We need the USB changes in here for additional patches to be able to
apply cleanly.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1  2 
MAINTAINERS
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci.h

diff --combined MAINTAINERS
@@@ -1739,13 -1739,17 +1739,17 @@@ ARM/Mediatek SoC suppor
  M:    Matthias Brugger <matthias.bgg@gmail.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  L:    linux-mediatek@lists.infradead.org (moderated for non-subscribers)
+ W:    https://mtk.bcnfs.org/
+ C:    irc://chat.freenode.net/linux-mediatek
  S:    Maintained
  F:    arch/arm/boot/dts/mt6*
  F:    arch/arm/boot/dts/mt7*
  F:    arch/arm/boot/dts/mt8*
  F:    arch/arm/mach-mediatek/
  F:    arch/arm64/boot/dts/mediatek/
+ F:    drivers/soc/mediatek/
  N:    mtk
+ N:    mt[678]
  K:    mediatek
  
  ARM/Mediatek USB3 PHY DRIVER
@@@ -4843,6 -4847,7 +4847,7 @@@ F:      include/uapi/drm/vmwgfx_drm.
  
  DRM DRIVERS
  M:    David Airlie <airlied@linux.ie>
+ M:    Daniel Vetter <daniel@ffwll.ch>
  L:    dri-devel@lists.freedesktop.org
  T:    git git://anongit.freedesktop.org/drm/drm
  B:    https://bugs.freedesktop.org/
@@@ -6261,7 -6266,6 +6266,7 @@@ T:      git git://git.kernel.org/pub/scm/lin
  S:    Supported
  F:    drivers/phy/
  F:    include/linux/phy/
 +F:    Documentation/devicetree/bindings/phy/
  
  GENERIC PINCTRL I2C DEMULTIPLEXER DRIVER
  M:    Wolfram Sang <wsa+renesas@sang-engineering.com>
@@@ -8939,7 -8943,7 +8944,7 @@@ F:      arch/mips/boot/dts/img/pistachio_mar
  
  MARVELL 88E6XXX ETHERNET SWITCH FABRIC DRIVER
  M:    Andrew Lunn <andrew@lunn.ch>
- M:    Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+ M:    Vivien Didelot <vivien.didelot@gmail.com>
  L:    netdev@vger.kernel.org
  S:    Maintained
  F:    drivers/net/dsa/mv88e6xxx/
@@@ -9444,6 -9448,13 +9449,13 @@@ F:    drivers/media/platform/mtk-vpu
  F:    Documentation/devicetree/bindings/media/mediatek-vcodec.txt
  F:    Documentation/devicetree/bindings/media/mediatek-vpu.txt
  
+ MEDIATEK MT76 WIRELESS LAN DRIVER
+ M:    Felix Fietkau <nbd@nbd.name>
+ M:    Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ L:    linux-wireless@vger.kernel.org
+ S:    Maintained
+ F:    drivers/net/wireless/mediatek/mt76/
  MEDIATEK MT7601U WIRELESS LAN DRIVER
  M:    Jakub Kicinski <kubakici@wp.pl>
  L:    linux-wireless@vger.kernel.org
@@@ -10006,12 -10017,9 +10018,9 @@@ S:  Odd Fixe
  F:    drivers/media/radio/radio-miropcm20*
  
  MMP SUPPORT
- M:    Eric Miao <eric.y.miao@gmail.com>
- M:    Haojian Zhuang <haojian.zhuang@gmail.com>
+ R:    Lubomir Rintel <lkundrak@v3.sk>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
- T:    git git://github.com/hzhuang1/linux.git
- T:    git git://git.linaro.org/people/ycmiao/pxa-linux.git
- S:    Maintained
+ S:    Odd Fixes
  F:    arch/arm/boot/dts/mmp*
  F:    arch/arm/mach-mmp/
  
@@@ -10417,7 -10425,7 +10426,7 @@@ F:   drivers/net/wireless
  
  NETWORKING [DSA]
  M:    Andrew Lunn <andrew@lunn.ch>
- M:    Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+ M:    Vivien Didelot <vivien.didelot@gmail.com>
  M:    Florian Fainelli <f.fainelli@gmail.com>
  S:    Maintained
  F:    Documentation/devicetree/bindings/net/dsa/
@@@ -1165,13 -1165,28 +1165,13 @@@ static void mvpp22_gop_setup_irq(struc
   */
  static int mvpp22_comphy_init(struct mvpp2_port *port)
  {
 -      enum phy_mode mode;
        int ret;
  
        if (!port->comphy)
                return 0;
  
 -      switch (port->phy_interface) {
 -      case PHY_INTERFACE_MODE_SGMII:
 -      case PHY_INTERFACE_MODE_1000BASEX:
 -              mode = PHY_MODE_SGMII;
 -              break;
 -      case PHY_INTERFACE_MODE_2500BASEX:
 -              mode = PHY_MODE_2500SGMII;
 -              break;
 -      case PHY_INTERFACE_MODE_10GKR:
 -              mode = PHY_MODE_10GKR;
 -              break;
 -      default:
 -              return -EINVAL;
 -      }
 -
 -      ret = phy_set_mode(port->comphy, mode);
 +      ret = phy_set_mode_ext(port->comphy, PHY_MODE_ETHERNET,
 +                             port->phy_interface);
        if (ret)
                return ret;
  
@@@ -4390,12 -4405,15 +4390,15 @@@ static void mvpp2_phylink_validate(stru
        case PHY_INTERFACE_MODE_10GKR:
        case PHY_INTERFACE_MODE_XAUI:
        case PHY_INTERFACE_MODE_NA:
-               phylink_set(mask, 10000baseCR_Full);
-               phylink_set(mask, 10000baseSR_Full);
-               phylink_set(mask, 10000baseLR_Full);
-               phylink_set(mask, 10000baseLRM_Full);
-               phylink_set(mask, 10000baseER_Full);
-               phylink_set(mask, 10000baseKR_Full);
+               if (port->gop_id == 0) {
+                       phylink_set(mask, 10000baseT_Full);
+                       phylink_set(mask, 10000baseCR_Full);
+                       phylink_set(mask, 10000baseSR_Full);
+                       phylink_set(mask, 10000baseLR_Full);
+                       phylink_set(mask, 10000baseLRM_Full);
+                       phylink_set(mask, 10000baseER_Full);
+                       phylink_set(mask, 10000baseKR_Full);
+               }
                /* Fall-through */
        case PHY_INTERFACE_MODE_RGMII:
        case PHY_INTERFACE_MODE_RGMII_ID:
                phylink_set(mask, 10baseT_Full);
                phylink_set(mask, 100baseT_Half);
                phylink_set(mask, 100baseT_Full);
-               phylink_set(mask, 10000baseT_Full);
                /* Fall-through */
        case PHY_INTERFACE_MODE_1000BASEX:
        case PHY_INTERFACE_MODE_2500BASEX:
@@@ -714,6 -714,13 +714,6 @@@ void xhci_test_and_clear_bit(struct xhc
        }
  }
  
 -/* Updates Link Status for USB 2.1 port */
 -static void xhci_hub_report_usb2_link_state(u32 *status, u32 status_reg)
 -{
 -      if ((status_reg & PORT_PLS_MASK) == XDEV_U2)
 -              *status |= USB_PORT_STAT_L1;
 -}
 -
  /* Updates Link Status for super Speed port */
  static void xhci_hub_report_usb3_link_state(struct xhci_hcd *xhci,
                u32 *status, u32 status_reg)
@@@ -795,100 -802,6 +795,100 @@@ static void xhci_del_comp_mod_timer(str
        }
  }
  
 +static int xhci_handle_usb2_port_link_resume(struct xhci_port *port,
 +                                           u32 *status, u32 portsc,
 +                                           unsigned long flags)
 +{
 +      struct xhci_bus_state *bus_state;
 +      struct xhci_hcd *xhci;
 +      struct usb_hcd *hcd;
 +      int slot_id;
 +      u32 wIndex;
 +
 +      hcd = port->rhub->hcd;
 +      bus_state = &port->rhub->bus_state;
 +      xhci = hcd_to_xhci(hcd);
 +      wIndex = port->hcd_portnum;
 +
 +      if ((portsc & PORT_RESET) || !(portsc & PORT_PE)) {
 +              *status = 0xffffffff;
 +              return -EINVAL;
 +      }
 +      /* did port event handler already start resume timing? */
 +      if (!bus_state->resume_done[wIndex]) {
 +              /* If not, maybe we are in a host initated resume? */
 +              if (test_bit(wIndex, &bus_state->resuming_ports)) {
 +                      /* Host initated resume doesn't time the resume
 +                       * signalling using resume_done[].
 +                       * It manually sets RESUME state, sleeps 20ms
 +                       * and sets U0 state. This should probably be
 +                       * changed, but not right now.
 +                       */
 +              } else {
 +                      /* port resume was discovered now and here,
 +                       * start resume timing
 +                       */
 +                      unsigned long timeout = jiffies +
 +                              msecs_to_jiffies(USB_RESUME_TIMEOUT);
 +
 +                      set_bit(wIndex, &bus_state->resuming_ports);
 +                      bus_state->resume_done[wIndex] = timeout;
 +                      mod_timer(&hcd->rh_timer, timeout);
 +                      usb_hcd_start_port_resume(&hcd->self, wIndex);
 +              }
 +      /* Has resume been signalled for USB_RESUME_TIME yet? */
 +      } else if (time_after_eq(jiffies, bus_state->resume_done[wIndex])) {
 +              int time_left;
 +
 +              xhci_dbg(xhci, "Resume USB2 port %d\n", wIndex + 1);
 +              bus_state->resume_done[wIndex] = 0;
 +              clear_bit(wIndex, &bus_state->resuming_ports);
 +
 +              set_bit(wIndex, &bus_state->rexit_ports);
 +
 +              xhci_test_and_clear_bit(xhci, port, PORT_PLC);
 +              xhci_set_link_state(xhci, port, XDEV_U0);
 +
 +              spin_unlock_irqrestore(&xhci->lock, flags);
 +              time_left = wait_for_completion_timeout(
 +                      &bus_state->rexit_done[wIndex],
 +                      msecs_to_jiffies(XHCI_MAX_REXIT_TIMEOUT_MS));
 +              spin_lock_irqsave(&xhci->lock, flags);
 +
 +              if (time_left) {
 +                      slot_id = xhci_find_slot_id_by_port(hcd, xhci,
 +                                                          wIndex + 1);
 +                      if (!slot_id) {
 +                              xhci_dbg(xhci, "slot_id is zero\n");
 +                              *status = 0xffffffff;
 +                              return -ENODEV;
 +                      }
 +                      xhci_ring_device(xhci, slot_id);
 +              } else {
 +                      int port_status = readl(port->addr);
 +
 +                      xhci_warn(xhci, "Port resume %i msec timed out, portsc = 0x%x\n",
 +                                XHCI_MAX_REXIT_TIMEOUT_MS,
 +                                port_status);
 +                      *status |= USB_PORT_STAT_SUSPEND;
 +                      clear_bit(wIndex, &bus_state->rexit_ports);
 +              }
 +
 +              usb_hcd_end_port_resume(&hcd->self, wIndex);
 +              bus_state->port_c_suspend |= 1 << wIndex;
 +              bus_state->suspended_ports &= ~(1 << wIndex);
 +      } else {
 +              /*
 +               * The resume has been signaling for less than
 +               * USB_RESUME_TIME. Report the port status as SUSPEND,
 +               * let the usbcore check port status again and clear
 +               * resume signaling later.
 +               */
 +              *status |= USB_PORT_STAT_SUSPEND;
 +      }
 +      return 0;
 +}
 +
  static u32 xhci_get_ext_port_status(u32 raw_port_status, u32 port_li)
  {
        u32 ext_stat = 0;
        return ext_stat;
  }
  
 +static void xhci_get_usb3_port_status(struct xhci_port *port, u32 *status,
 +                                    u32 portsc)
 +{
 +      struct xhci_bus_state *bus_state;
 +      struct xhci_hcd *xhci;
 +      u32 link_state;
 +      u32 portnum;
 +
 +      bus_state = &port->rhub->bus_state;
 +      xhci = hcd_to_xhci(port->rhub->hcd);
 +      link_state = portsc & PORT_PLS_MASK;
 +      portnum = port->hcd_portnum;
 +
 +      /* USB3 specific wPortChange bits
 +       *
 +       * Port link change with port in resume state should not be
 +       * reported to usbcore, as this is an internal state to be
 +       * handled by xhci driver. Reporting PLC to usbcore may
 +       * cause usbcore clearing PLC first and port change event
 +       * irq won't be generated.
 +       */
 +
 +      if (portsc & PORT_PLC && (link_state != XDEV_RESUME))
 +              *status |= USB_PORT_STAT_C_LINK_STATE << 16;
 +      if (portsc & PORT_WRC)
 +              *status |= USB_PORT_STAT_C_BH_RESET << 16;
 +      if (portsc & PORT_CEC)
 +              *status |= USB_PORT_STAT_C_CONFIG_ERROR << 16;
 +
 +      /* USB3 specific wPortStatus bits */
 +      if (portsc & PORT_POWER) {
 +              *status |= USB_SS_PORT_STAT_POWER;
 +              /* link state handling */
 +              if (link_state == XDEV_U0)
 +                      bus_state->suspended_ports &= ~(1 << portnum);
 +      }
 +
 +      xhci_hub_report_usb3_link_state(xhci, status, portsc);
 +      xhci_del_comp_mod_timer(xhci, portsc, portnum);
 +}
 +
 +static void xhci_get_usb2_port_status(struct xhci_port *port, u32 *status,
 +                                    u32 portsc, unsigned long flags)
 +{
 +      struct xhci_bus_state *bus_state;
 +      u32 link_state;
 +      u32 portnum;
 +      int ret;
 +
 +      bus_state = &port->rhub->bus_state;
 +      link_state = portsc & PORT_PLS_MASK;
 +      portnum = port->hcd_portnum;
 +
 +      /* USB2 wPortStatus bits */
 +      if (portsc & PORT_POWER) {
 +              *status |= USB_PORT_STAT_POWER;
 +
 +              /* link state is only valid if port is powered */
 +              if (link_state == XDEV_U3)
 +                      *status |= USB_PORT_STAT_SUSPEND;
 +              if (link_state == XDEV_U2)
 +                      *status |= USB_PORT_STAT_L1;
 +              if (link_state == XDEV_U0) {
 +                      bus_state->resume_done[portnum] = 0;
 +                      clear_bit(portnum, &bus_state->resuming_ports);
 +                      if (bus_state->suspended_ports & (1 << portnum)) {
 +                              bus_state->suspended_ports &= ~(1 << portnum);
 +                              bus_state->port_c_suspend |= 1 << portnum;
 +                      }
 +              }
 +              if (link_state == XDEV_RESUME) {
 +                      ret = xhci_handle_usb2_port_link_resume(port, status,
 +                                                              portsc, flags);
 +                      if (ret)
 +                              return;
 +              }
 +      }
 +}
 +
  /*
   * Converts a raw xHCI port status into the format that external USB 2.0 or USB
   * 3.0 hubs use.
@@@ -1001,14 -835,16 +1001,14 @@@ static u32 xhci_get_port_status(struct 
        __releases(&xhci->lock)
        __acquires(&xhci->lock)
  {
 -      struct xhci_hcd *xhci = hcd_to_xhci(hcd);
        u32 status = 0;
 -      int slot_id;
        struct xhci_hub *rhub;
        struct xhci_port *port;
  
        rhub = xhci_get_rhub(hcd);
        port = rhub->ports[wIndex];
  
 -      /* wPortChange bits */
 +      /* common wPortChange bits */
        if (raw_port_status & PORT_CSC)
                status |= USB_PORT_STAT_C_CONNECTION << 16;
        if (raw_port_status & PORT_PEC)
                status |= USB_PORT_STAT_C_OVERCURRENT << 16;
        if ((raw_port_status & PORT_RC))
                status |= USB_PORT_STAT_C_RESET << 16;
 -      /* USB3.0 only */
 -      if (hcd->speed >= HCD_USB3) {
 -              /* Port link change with port in resume state should not be
 -               * reported to usbcore, as this is an internal state to be
 -               * handled by xhci driver. Reporting PLC to usbcore may
 -               * cause usbcore clearing PLC first and port change event
 -               * irq won't be generated.
 -               */
 -              if ((raw_port_status & PORT_PLC) &&
 -                      (raw_port_status & PORT_PLS_MASK) != XDEV_RESUME)
 -                      status |= USB_PORT_STAT_C_LINK_STATE << 16;
 -              if ((raw_port_status & PORT_WRC))
 -                      status |= USB_PORT_STAT_C_BH_RESET << 16;
 -              if ((raw_port_status & PORT_CEC))
 -                      status |= USB_PORT_STAT_C_CONFIG_ERROR << 16;
 -      }
  
 -      if (hcd->speed < HCD_USB3) {
 -              if ((raw_port_status & PORT_PLS_MASK) == XDEV_U3
 -                              && (raw_port_status & PORT_POWER))
 -                      status |= USB_PORT_STAT_SUSPEND;
 +      /* common wPortStatus bits */
 +      if (raw_port_status & PORT_CONNECT) {
 +              status |= USB_PORT_STAT_CONNECTION;
 +              status |= xhci_port_speed(raw_port_status);
        }
 -      if ((raw_port_status & PORT_PLS_MASK) == XDEV_RESUME &&
 -              !DEV_SUPERSPEED_ANY(raw_port_status) && hcd->speed < HCD_USB3) {
 -              if ((raw_port_status & PORT_RESET) ||
 -                              !(raw_port_status & PORT_PE))
 -                      return 0xffffffff;
 -              /* did port event handler already start resume timing? */
 -              if (!bus_state->resume_done[wIndex]) {
 -                      /* If not, maybe we are in a host initated resume? */
 -                      if (test_bit(wIndex, &bus_state->resuming_ports)) {
 -                              /* Host initated resume doesn't time the resume
 -                               * signalling using resume_done[].
 -                               * It manually sets RESUME state, sleeps 20ms
 -                               * and sets U0 state. This should probably be
 -                               * changed, but not right now.
 -                               */
 -                      } else {
 -                              /* port resume was discovered now and here,
 -                               * start resume timing
 -                               */
 -                              unsigned long timeout = jiffies +
 -                                      msecs_to_jiffies(USB_RESUME_TIMEOUT);
 -
 -                              set_bit(wIndex, &bus_state->resuming_ports);
 -                              bus_state->resume_done[wIndex] = timeout;
 -                              mod_timer(&hcd->rh_timer, timeout);
 -                              usb_hcd_start_port_resume(&hcd->self, wIndex);
 -                      }
 -              /* Has resume been signalled for USB_RESUME_TIME yet? */
 -              } else if (time_after_eq(jiffies,
 -                                       bus_state->resume_done[wIndex])) {
 -                      int time_left;
 -
 -                      xhci_dbg(xhci, "Resume USB2 port %d\n",
 -                                      wIndex + 1);
 -                      bus_state->resume_done[wIndex] = 0;
 -                      clear_bit(wIndex, &bus_state->resuming_ports);
 -
 -                      set_bit(wIndex, &bus_state->rexit_ports);
 -
 -                      xhci_test_and_clear_bit(xhci, port, PORT_PLC);
 -                      xhci_set_link_state(xhci, port, XDEV_U0);
 -
 -                      spin_unlock_irqrestore(&xhci->lock, flags);
 -                      time_left = wait_for_completion_timeout(
 -                                      &bus_state->rexit_done[wIndex],
 -                                      msecs_to_jiffies(
 -                                              XHCI_MAX_REXIT_TIMEOUT_MS));
 -                      spin_lock_irqsave(&xhci->lock, flags);
 -
 -                      if (time_left) {
 -                              slot_id = xhci_find_slot_id_by_port(hcd,
 -                                              xhci, wIndex + 1);
 -                              if (!slot_id) {
 -                                      xhci_dbg(xhci, "slot_id is zero\n");
 -                                      return 0xffffffff;
 -                              }
 -                              xhci_ring_device(xhci, slot_id);
 -                      } else {
 -                              int port_status = readl(port->addr);
 -                              xhci_warn(xhci, "Port resume took longer than %i msec, port status = 0x%x\n",
 -                                              XHCI_MAX_REXIT_TIMEOUT_MS,
 -                                              port_status);
 -                              status |= USB_PORT_STAT_SUSPEND;
 -                              clear_bit(wIndex, &bus_state->rexit_ports);
 -                      }
 +      if (raw_port_status & PORT_PE)
 +              status |= USB_PORT_STAT_ENABLE;
 +      if (raw_port_status & PORT_OC)
 +              status |= USB_PORT_STAT_OVERCURRENT;
 +      if (raw_port_status & PORT_RESET)
 +              status |= USB_PORT_STAT_RESET;
  
 -                      usb_hcd_end_port_resume(&hcd->self, wIndex);
 -                      bus_state->port_c_suspend |= 1 << wIndex;
 -                      bus_state->suspended_ports &= ~(1 << wIndex);
 -              } else {
 -                      /*
 -                       * The resume has been signaling for less than
 -                       * USB_RESUME_TIME. Report the port status as SUSPEND,
 -                       * let the usbcore check port status again and clear
 -                       * resume signaling later.
 -                       */
 -                      status |= USB_PORT_STAT_SUSPEND;
 -              }
 -      }
 +      /* USB2 and USB3 specific bits, including Port Link State */
 +      if (hcd->speed >= HCD_USB3)
 +              xhci_get_usb3_port_status(port, &status, raw_port_status);
 +      else
 +              xhci_get_usb2_port_status(port, &status, raw_port_status,
 +                                        flags);
        /*
         * Clear stale usb2 resume signalling variables in case port changed
         * state during resume signalling. For example on error
                usb_hcd_end_port_resume(&hcd->self, wIndex);
        }
  
 -
 -      if ((raw_port_status & PORT_PLS_MASK) == XDEV_U0 &&
 -          (raw_port_status & PORT_POWER)) {
 -              if (bus_state->suspended_ports & (1 << wIndex)) {
 -                      bus_state->suspended_ports &= ~(1 << wIndex);
 -                      if (hcd->speed < HCD_USB3)
 -                              bus_state->port_c_suspend |= 1 << wIndex;
 -              }
 -              bus_state->resume_done[wIndex] = 0;
 -              clear_bit(wIndex, &bus_state->resuming_ports);
 -      }
 -      if (raw_port_status & PORT_CONNECT) {
 -              status |= USB_PORT_STAT_CONNECTION;
 -              status |= xhci_port_speed(raw_port_status);
 -      }
 -      if (raw_port_status & PORT_PE)
 -              status |= USB_PORT_STAT_ENABLE;
 -      if (raw_port_status & PORT_OC)
 -              status |= USB_PORT_STAT_OVERCURRENT;
 -      if (raw_port_status & PORT_RESET)
 -              status |= USB_PORT_STAT_RESET;
 -      if (raw_port_status & PORT_POWER) {
 -              if (hcd->speed >= HCD_USB3)
 -                      status |= USB_SS_PORT_STAT_POWER;
 -              else
 -                      status |= USB_PORT_STAT_POWER;
 -      }
 -      /* Update Port Link State */
 -      if (hcd->speed >= HCD_USB3) {
 -              xhci_hub_report_usb3_link_state(xhci, &status, raw_port_status);
 -              /*
 -               * Verify if all USB3 Ports Have entered U0 already.
 -               * Delete Compliance Mode Timer if so.
 -               */
 -              xhci_del_comp_mod_timer(xhci, raw_port_status, wIndex);
 -      } else {
 -              xhci_hub_report_usb2_link_state(&status, raw_port_status);
 -      }
        if (bus_state->port_c_suspend & (1 << wIndex))
                status |= USB_PORT_STAT_C_SUSPEND << 16;
  
@@@ -1075,7 -1031,7 +1075,7 @@@ int xhci_hub_control(struct usb_hcd *hc
        rhub = xhci_get_rhub(hcd);
        ports = rhub->ports;
        max_ports = rhub->num_ports;
 -      bus_state = &xhci->bus_state[hcd_index(hcd)];
 +      bus_state = &rhub->bus_state;
  
        spin_lock_irqsave(&xhci->lock, flags);
        switch (typeReq) {
@@@ -1465,7 -1421,7 +1465,7 @@@ int xhci_hub_status_data(struct usb_hc
        rhub = xhci_get_rhub(hcd);
        ports = rhub->ports;
        max_ports = rhub->num_ports;
 -      bus_state = &xhci->bus_state[hcd_index(hcd)];
 +      bus_state = &rhub->bus_state;
  
        /* Initial status is no changes */
        retval = (max_ports + 8) / 8;
@@@ -1524,7 -1480,7 +1524,7 @@@ int xhci_bus_suspend(struct usb_hcd *hc
        rhub = xhci_get_rhub(hcd);
        ports = rhub->ports;
        max_ports = rhub->num_ports;
 -      bus_state = &xhci->bus_state[hcd_index(hcd)];
 +      bus_state = &rhub->bus_state;
        wake_enabled = hcd->self.root_hub->do_remote_wakeup;
  
        spin_lock_irqsave(&xhci->lock, flags);
                portsc_buf[port_index] = 0;
  
                /* Bail out if a USB3 port has a new device in link training */
-               if ((t1 & PORT_PLS_MASK) == XDEV_POLLING) {
+               if ((hcd->speed >= HCD_USB3) &&
+                   (t1 & PORT_PLS_MASK) == XDEV_POLLING) {
                        bus_state->bus_suspended = 0;
                        spin_unlock_irqrestore(&xhci->lock, flags);
                        xhci_dbg(xhci, "Bus suspend bailout, port in polling\n");
@@@ -1666,7 -1623,7 +1667,7 @@@ int xhci_bus_resume(struct usb_hcd *hcd
        rhub = xhci_get_rhub(hcd);
        ports = rhub->ports;
        max_ports = rhub->num_ports;
 -      bus_state = &xhci->bus_state[hcd_index(hcd)];
 +      bus_state = &rhub->bus_state;
  
        if (time_before(jiffies, bus_state->next_statechange))
                msleep(5);
  
  unsigned long xhci_get_resuming_ports(struct usb_hcd *hcd)
  {
 -      struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 -      struct xhci_bus_state *bus_state;
 -
 -      bus_state = &xhci->bus_state[hcd_index(hcd)];
 +      struct xhci_hub *rhub = xhci_get_rhub(hcd);
  
        /* USB3 port wakeups are reported via usb_wakeup_notification() */
 -      return bus_state->resuming_ports;       /* USB2 ports only */
 +      return rhub->bus_state.resuming_ports;  /* USB2 ports only */
  }
  
  #endif        /* CONFIG_PM */
diff --combined drivers/usb/host/xhci.h
@@@ -1682,6 -1682,13 +1682,6 @@@ struct xhci_bus_state 
   */
  #define       XHCI_MAX_REXIT_TIMEOUT_MS       20
  
 -static inline unsigned int hcd_index(struct usb_hcd *hcd)
 -{
 -      if (hcd->speed >= HCD_USB3)
 -              return 0;
 -      else
 -              return 1;
 -}
  struct xhci_port {
        __le32 __iomem          *addr;
        int                     hw_portnum;
@@@ -1693,8 -1700,6 +1693,8 @@@ struct xhci_hub 
        struct xhci_port        **ports;
        unsigned int            num_ports;
        struct usb_hcd          *hcd;
 +      /* keep track of bus suspend info */
 +      struct xhci_bus_state   bus_state;
        /* supported prococol extended capabiliy values */
        u8                      maj_rev;
        u8                      min_rev;
@@@ -1849,11 -1854,17 +1849,13 @@@ struct xhci_hcd 
  
        unsigned int            num_active_eps;
        unsigned int            limit_active_eps;
 -      /* There are two roothubs to keep track of bus suspend info for */
 -      struct xhci_bus_state   bus_state[2];
        struct xhci_port        *hw_ports;
        struct xhci_hub         usb2_rhub;
        struct xhci_hub         usb3_rhub;
 -      /* support xHCI 0.96 spec USB2 software LPM */
 -      unsigned                sw_lpm_support:1;
        /* support xHCI 1.0 spec USB2 hardware LPM */
        unsigned                hw_lpm_support:1;
+       /* Broken Suspend flag for SNPS Suspend resume issue */
+       unsigned                broken_suspend:1;
        /* cached usb2 extened protocol capabilites */
        u32                     *ext_caps;
        unsigned int            num_ext_caps;
        void                    *dbc;
        /* platform-specific data -- must come last */
        unsigned long           priv[0] __aligned(sizeof(s64));
-       /* Broken Suspend flag for SNPS Suspend resume issue */
-       u8                      broken_suspend;
  };
  
  /* Platform specific overrides to generic XHCI hc_driver ops */