kernel: bump 4.9 to 4.9.116
[openwrt/staging/chunkeey.git] / target / linux / layerscape / patches-4.9 / 817-usb-support-layerscape.patch
index 147b03ae27af1c3eb8199e65572d2c7ce6c76bde..9225e93c1a5b138c4b86ddc1a5664ed60c3905fd 100644 (file)
@@ -1,9 +1,9 @@
-From f8daa8e984213554008e73cd155530dceec5a109 Mon Sep 17 00:00:00 2001
+From a2a97f0d2c07a772899ca09967547bea6c9124c5 Mon Sep 17 00:00:00 2001
 From: Yangbo Lu <yangbo.lu@nxp.com>
-Date: Wed, 27 Sep 2017 10:34:07 +0800
-Subject: [PATCH] usb: support layerscape
+Date: Wed, 17 Jan 2018 15:46:03 +0800
+Subject: [PATCH 29/30] usb: support layerscape
 
-This is a integrated patch for layerscape usb support.
+This is an integrated patch for layerscape usb support.
 
 Signed-off-by: yinbo.zhu <yinbo.zhu@nxp.com>
 Signed-off-by: Ramneek Mehresh <ramneek.mehresh@freescale.com>
@@ -15,25 +15,86 @@ Signed-off-by: Suresh Gupta <suresh.gupta@freescale.com>
 Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
 ---
+ drivers/net/usb/cdc_ether.c           |   8 +
+ drivers/net/usb/r8152.c               |   6 +
  drivers/usb/common/common.c           |  50 ++++++
  drivers/usb/core/hub.c                |   8 +
- drivers/usb/dwc3/core.c               | 235 ++++++++++++++++++++++++++-
- drivers/usb/dwc3/core.h               |  46 +++++-
- drivers/usb/dwc3/host.c               |  15 +-
+ drivers/usb/dwc3/core.c               | 243 ++++++++++++++++++++++++++++-
+ drivers/usb/dwc3/core.h               |  51 ++++++-
+ drivers/usb/dwc3/ep0.c                |   4 +-
+ drivers/usb/dwc3/gadget.c             |   7 +
+ drivers/usb/dwc3/host.c               |  24 ++-
  drivers/usb/gadget/udc/fsl_udc_core.c |  46 +++---
  drivers/usb/gadget/udc/fsl_usb2_udc.h |  16 +-
  drivers/usb/host/Kconfig              |   2 +-
- drivers/usb/host/ehci-fsl.c           | 289 +++++++++++++++++++++++++++++++---
+ drivers/usb/host/ehci-fsl.c           | 279 +++++++++++++++++++++++++++++++---
  drivers/usb/host/ehci-fsl.h           |   3 +
- drivers/usb/host/ehci-hub.c           |   2 +
- drivers/usb/host/ehci.h               |   +
+ drivers/usb/host/ehci-hub.c           |   4 +
+ drivers/usb/host/ehci.h               |   9 ++
  drivers/usb/host/fsl-mph-dr-of.c      |  12 ++
+ drivers/usb/host/xhci-plat.c          |  10 ++
+ drivers/usb/host/xhci-ring.c          |  29 +++-
+ drivers/usb/host/xhci.c               |  38 ++++-
+ drivers/usb/host/xhci.h               |   5 +-
  drivers/usb/phy/phy-fsl-usb.c         |  59 +++++--
  drivers/usb/phy/phy-fsl-usb.h         |   8 +
  include/linux/usb.h                   |   1 +
  include/linux/usb/of.h                |   2 +
17 files changed, 726 insertions(+), 73 deletions(-)
25 files changed, 836 insertions(+), 88 deletions(-)
 
+--- a/drivers/net/usb/cdc_ether.c
++++ b/drivers/net/usb/cdc_ether.c
+@@ -533,6 +533,7 @@ static const struct driver_info wwan_inf
+ #define LINKSYS_VENDOR_ID     0x13b1
+ #define NVIDIA_VENDOR_ID      0x0955
+ #define HP_VENDOR_ID          0x03f0
++#define TPLINK_VENDOR_ID      0x2357
+ static const struct usb_device_id     products[] = {
+ /* BLACKLIST !!
+@@ -742,6 +743,13 @@ static const struct usb_device_id produc
+                       USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+       .driver_info = 0,
+ },
++
++      /* TP-LINK UE300 USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */
++{
++      USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, 0x0601, USB_CLASS_COMM,
++                      USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
++      .driver_info = 0,
++},
+ /* WHITELIST!!!
+  *
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -521,6 +521,7 @@ enum rtl8152_flags {
+ #define VENDOR_ID_LENOVO              0x17ef
+ #define VENDOR_ID_LINKSYS             0x13b1
+ #define VENDOR_ID_NVIDIA              0x0955
++#define VENDOR_ID_TPLINK              0x2357
+ #define MCU_TYPE_PLA                  0x0100
+ #define MCU_TYPE_USB                  0x0000
+@@ -1817,6 +1818,10 @@ static int rx_bottom(struct r8152 *tp, i
+                       unsigned int pkt_len;
+                       struct sk_buff *skb;
++                      /* limite the skb numbers for rx_queue */
++                      if (unlikely(skb_queue_len(&tp->rx_queue) >= 1000))
++                              break;
++
+                       pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
+                       if (pkt_len < ETH_ZLEN)
+                               break;
+@@ -4510,6 +4515,7 @@ static struct usb_device_id rtl8152_tabl
+       {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO,  0x304f)},
+       {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)},
+       {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA,  0x09ff)},
++      {REALTEK_USB_DEVICE(VENDOR_ID_TPLINK,  0x0601)},
+       {}
+ };
 --- a/drivers/usb/common/common.c
 +++ b/drivers/usb/common/common.c
 @@ -105,6 +105,56 @@ static const char *const usb_dr_modes[]
@@ -95,7 +156,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
        int ret;
 --- a/drivers/usb/core/hub.c
 +++ b/drivers/usb/core/hub.c
-@@ -4412,6 +4412,14 @@ hub_port_init(struct usb_hub *hub, struc
+@@ -4427,6 +4427,14 @@ hub_port_init(struct usb_hub *hub, struc
        else
                speed = usb_speed_string(udev->speed);
  
@@ -145,7 +206,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
                if (IS_ENABLED(CONFIG_USB_DWC3_HOST))
                        mode = USB_DR_MODE_HOST;
                else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET))
-@@ -213,8 +232,9 @@ static void dwc3_frame_length_adjustment
+@@ -227,8 +246,9 @@ static void dwc3_frame_length_adjustment
  
        reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
        dft = reg & DWC3_GFLADJ_30MHZ_MASK;
@@ -157,7 +218,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
                reg &= ~DWC3_GFLADJ_30MHZ_MASK;
                reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj;
                dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
-@@ -579,6 +599,99 @@ static int dwc3_phy_setup(struct dwc3 *d
+@@ -599,6 +619,99 @@ static int dwc3_phy_setup(struct dwc3 *d
        return 0;
  }
  
@@ -257,7 +318,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
  static void dwc3_core_exit(struct dwc3 *dwc)
  {
        dwc3_event_buffers_cleanup(dwc);
-@@ -721,6 +834,8 @@ static int dwc3_core_init(struct dwc3 *d
+@@ -741,6 +854,8 @@ static int dwc3_core_init(struct dwc3 *d
        if (ret)
                goto err1;
  
@@ -266,7 +327,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
        /* Adjust Frame Length */
        dwc3_frame_length_adjustment(dwc);
  
-@@ -919,11 +1034,109 @@ static void dwc3_core_exit_mode(struct d
+@@ -939,11 +1054,117 @@ static void dwc3_core_exit_mode(struct d
        }
  }
  
@@ -311,6 +372,12 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
 +                              &hird_threshold);
 +      dwc->usb3_lpm_capable = device_property_read_bool(dev,
 +                              "snps,usb3_lpm_capable");
++      dwc->quirk_reverse_in_out = device_property_read_bool(dev,
++                              "snps,quirk_reverse_in_out");
++      dwc->quirk_stop_transfer_in_block = device_property_read_bool(dev,
++                              "snps,quirk_stop_transfer_in_block");
++      dwc->quirk_stop_ep_in_u1 = device_property_read_bool(dev,
++                              "snps,quirk_stop_ep_in_u1");
 +
 +      dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
 +
@@ -351,6 +418,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
 +
 +      dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
 +                              "snps,tx_de_emphasis_quirk");
++      dwc->disable_devinit_u1u2_quirk = device_property_read_bool(dev,
++                              "snps,disable_devinit_u1u2");
 +      device_property_read_u8(dev, "snps,tx_de_emphasis",
 +                              &tx_de_emphasis);
 +      device_property_read_string(dev, "snps,hsphy_interface",
@@ -376,7 +445,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
        struct resource         *res;
        struct dwc3             *dwc;
        u8                      lpm_nyet_threshold;
-@@ -955,6 +1168,11 @@ static int dwc3_probe(struct platform_de
+@@ -975,6 +1196,11 @@ static int dwc3_probe(struct platform_de
        dwc->xhci_resources[0].flags = res->flags;
        dwc->xhci_resources[0].name = res->name;
  
@@ -388,7 +457,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
        res->start += DWC3_GLOBALS_REGS_START;
  
        /*
-@@ -997,6 +1215,12 @@ static int dwc3_probe(struct platform_de
+@@ -1017,6 +1243,12 @@ static int dwc3_probe(struct platform_de
        dwc->usb3_lpm_capable = device_property_read_bool(dev,
                                "snps,usb3_lpm_capable");
  
@@ -401,7 +470,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
        dwc->disable_scramble_quirk = device_property_read_bool(dev,
                                "snps,disable_scramble_quirk");
        dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
-@@ -1041,6 +1265,8 @@ static int dwc3_probe(struct platform_de
+@@ -1061,6 +1293,8 @@ static int dwc3_probe(struct platform_de
        dwc->hird_threshold = hird_threshold
                | (dwc->is_utmi_l1_suspend << 4);
  
@@ -410,7 +479,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
        platform_set_drvdata(pdev, dwc);
        dwc3_cache_hwparams(dwc);
  
-@@ -1064,6 +1290,11 @@ static int dwc3_probe(struct platform_de
+@@ -1084,6 +1318,11 @@ static int dwc3_probe(struct platform_de
        if (ret < 0)
                goto err1;
  
@@ -465,7 +534,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
  /* Global Debug Queue/FIFO Space Available Register */
  #define DWC3_GDBGFIFOSPACE_NUM(n)     ((n) & 0x1f)
  #define DWC3_GDBGFIFOSPACE_TYPE(n)    (((n) << 5) & 0x1e0)
-@@ -180,7 +207,6 @@
+@@ -182,7 +209,6 @@
  #define DWC3_GCTL_CLK_PIPE    (1)
  #define DWC3_GCTL_CLK_PIPEHALF        (2)
  #define DWC3_GCTL_CLK_MASK    (3)
@@ -473,7 +542,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
  #define DWC3_GCTL_PRTCAP(n)   (((n) & (3 << 12)) >> 12)
  #define DWC3_GCTL_PRTCAPDIR(n)        ((n) << 12)
  #define DWC3_GCTL_PRTCAP_HOST 1
-@@ -289,6 +315,10 @@
+@@ -294,6 +320,10 @@
  /* Global Frame Length Adjustment Register */
  #define DWC3_GFLADJ_30MHZ_SDBND_SEL           (1 << 7)
  #define DWC3_GFLADJ_30MHZ_MASK                        0x3f
@@ -484,7 +553,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
  
  /* Global User Control Register 2 */
  #define DWC3_GUCTL2_RST_ACTBITLATER           (1 << 14)
-@@ -753,6 +783,7 @@ struct dwc3_scratchpad_array {
+@@ -758,6 +788,7 @@ struct dwc3_scratchpad_array {
   * @regs: base address for our registers
   * @regs_size: address space size
   * @fladj: frame length adjustment
@@ -492,7 +561,15 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
   * @irq_gadget: peripheral controller's IRQ number
   * @nr_scratch: number of scratch buffers
   * @u1u2: only used on revisions <1.83a for workaround
-@@ -847,6 +878,7 @@ struct dwc3 {
+@@ -834,6 +865,7 @@ struct dwc3_scratchpad_array {
+  *    1       - -3.5dB de-emphasis
+  *    2       - No de-emphasis
+  *    3       - Reserved
++ * @disable_devinit_u1u2_quirk: disable device-initiated U1/U2 request.
+  */
+ struct dwc3 {
+       struct usb_ctrlrequest  *ctrl_req;
+@@ -852,6 +884,7 @@ struct dwc3 {
        spinlock_t              lock;
  
        struct device           *dev;
@@ -500,7 +577,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
  
        struct platform_device  *xhci;
        struct resource         xhci_resources[DWC3_XHCI_RESOURCES_NUM];
-@@ -872,6 +904,12 @@ struct dwc3 {
+@@ -877,6 +910,12 @@ struct dwc3 {
        enum usb_phy_interface  hsphy_mode;
  
        u32                     fladj;
@@ -513,7 +590,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
        u32                     irq_gadget;
        u32                     nr_scratch;
        u32                     u1u2;
-@@ -948,9 +986,12 @@ struct dwc3 {
+@@ -953,9 +992,12 @@ struct dwc3 {
        unsigned                ep0_bounced:1;
        unsigned                ep0_expect_in:1;
        unsigned                has_hibernation:1;
@@ -526,7 +603,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
        unsigned                pending_events:1;
        unsigned                pullups_connected:1;
        unsigned                setup_packet_pending:1;
-@@ -971,9 +1012,12 @@ struct dwc3 {
+@@ -976,9 +1018,16 @@ struct dwc3 {
        unsigned                dis_rxdet_inp3_quirk:1;
        unsigned                dis_u2_freeclk_exists_quirk:1;
        unsigned                dis_del_phy_power_chg_quirk:1;
@@ -534,11 +611,52 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
  
        unsigned                tx_de_emphasis_quirk:1;
        unsigned                tx_de_emphasis:2;
++      unsigned                disable_devinit_u1u2_quirk:1;
++      unsigned                quirk_reverse_in_out:1;
++      unsigned                quirk_stop_transfer_in_block:1;
++      unsigned                quirk_stop_ep_in_u1:1;
 +
 +      u16                     imod_interval;
  };
  
  /* -------------------------------------------------------------------------- */
+--- a/drivers/usb/dwc3/ep0.c
++++ b/drivers/usb/dwc3/ep0.c
+@@ -360,9 +360,9 @@ static int dwc3_ep0_handle_status(struct
+               if ((dwc->speed == DWC3_DSTS_SUPERSPEED) ||
+                   (dwc->speed == DWC3_DSTS_SUPERSPEED_PLUS)) {
+                       reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+-                      if (reg & DWC3_DCTL_INITU1ENA)
++                      if ((reg & DWC3_DCTL_INITU1ENA) && !dwc->disable_devinit_u1u2_quirk)
+                               usb_status |= 1 << USB_DEV_STAT_U1_ENABLED;
+-                      if (reg & DWC3_DCTL_INITU2ENA)
++                      if ((reg & DWC3_DCTL_INITU2ENA) && !dwc->disable_devinit_u1u2_quirk)
+                               usb_status |= 1 << USB_DEV_STAT_U2_ENABLED;
+               }
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2932,6 +2932,7 @@ static irqreturn_t dwc3_interrupt(int ir
+ int dwc3_gadget_init(struct dwc3 *dwc)
+ {
+       int ret, irq;
++      u32     reg;
+       struct platform_device *dwc3_pdev = to_platform_device(dwc->dev);
+       irq = platform_get_irq_byname(dwc3_pdev, "peripheral");
+@@ -3046,6 +3047,12 @@ int dwc3_gadget_init(struct dwc3 *dwc)
+               goto err5;
+       }
++      if (dwc->disable_devinit_u1u2_quirk) {
++              reg = dwc3_readl(dwc->regs, DWC3_DCTL);
++              reg &= ~(DWC3_DCTL_INITU1ENA | DWC3_DCTL_INITU2ENA);
++              dwc3_writel(dwc->regs, DWC3_DCTL, reg);
++      }
++
+       return 0;
+ err5:
 --- a/drivers/usb/dwc3/host.c
 +++ b/drivers/usb/dwc3/host.c
 @@ -17,6 +17,8 @@
@@ -574,6 +692,22 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
        dwc->xhci = xhci;
  
        ret = platform_device_add_resources(xhci, dwc->xhci_resources,
+@@ -90,6 +101,15 @@ int dwc3_host_init(struct dwc3 *dwc)
+       memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props));
++      if (dwc->quirk_reverse_in_out)
++              props[prop_idx++].name = "quirk-reverse-in-out";
++
++      if (dwc->quirk_stop_transfer_in_block)
++              props[prop_idx++].name = "quirk-stop-transfer-in-block";
++
++      if (dwc->quirk_stop_ep_in_u1)
++              props[prop_idx++].name = "quirk-stop-ep-in-u1";
++
+       if (dwc->usb3_lpm_capable)
+               props[prop_idx++].name = "usb3-lpm-capable";
 --- a/drivers/usb/gadget/udc/fsl_udc_core.c
 +++ b/drivers/usb/gadget/udc/fsl_udc_core.c
 @@ -198,7 +198,11 @@ __acquires(ep->udc->lock)
@@ -688,7 +822,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
                curr_ep = get_ep_by_pipe(udc, i);
  
                /* If the ep is configured */
--              if (curr_ep->name == NULL) {
+-              if (!curr_ep->ep.name) {
 +              if (strncmp(curr_ep->name, "ep", 2)) {
                        WARNING("Invalid EP?");
                        continue;
@@ -801,15 +935,17 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
          Variation of ARC USB block used in some Freescale chips.
 --- a/drivers/usb/host/ehci-fsl.c
 +++ b/drivers/usb/host/ehci-fsl.c
-@@ -37,13 +37,141 @@
+@@ -36,15 +36,127 @@
+ #include <linux/platform_device.h>
  #include <linux/fsl_devices.h>
  #include <linux/of_platform.h>
++#include <linux/io.h>
++
 +#ifdef CONFIG_PPC
 +#include <asm/fsl_pm.h>
 +#include <linux/suspend.h>
 +#endif
-+
  #include "ehci.h"
  #include "ehci-fsl.h"
  
@@ -850,13 +986,23 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
  #define DRV_NAME "ehci-fsl"
  
  static struct hc_driver __read_mostly fsl_ehci_hc_driver;
 +struct ehci_fsl {
-+       /* store current hcd state for otg;
-+      * have_hcd is true when host drv al already part of otg framework,
-+      * otherwise false;
-+      * hcd_add is true when otg framework wants to add host
-+      * drv as part of otg;flase when it wants to remove it
-+      */
++      struct ehci_hcd ehci;
++
++#ifdef CONFIG_PM
++struct ehci_regs saved_regs;
++struct ccsr_usb_phy saved_phy_regs;
++/* Saved USB PHY settings, need to restore after deep sleep. */
++u32 usb_ctrl;
++#endif
++      /*
++       * store current hcd state for otg;
++       * have_hcd is true when host drv al already part of otg framework,
++       * otherwise false;
++       * hcd_add is true when otg framework wants to add host
++       * drv as part of otg;flase when it wants to remove it
++       */
 +unsigned have_hcd:1;
 +unsigned hcd_add:1;
 +};
@@ -883,7 +1029,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
 +      /* host, gadget and otg share same int line */
 +      retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
 +      if (retval == 0)
-+      ehci_fsl->have_hcd = 1;
++              ehci_fsl->have_hcd = 1;
 +      } else if (!ehci_fsl->hcd_add && ehci_fsl->have_hcd) {
 +              usb_remove_hcd(hcd);
 +              ehci_fsl->have_hcd = 0;
@@ -891,59 +1037,33 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
 +}
 +#endif
 +
-+struct ehci_fsl {
-+      struct ehci_hcd ehci;
-+
-+#ifdef CONFIG_PM
-+struct ehci_regs saved_regs;
-+struct ccsr_usb_phy saved_phy_regs;
-+/* Saved USB PHY settings, need to restore after deep sleep. */
-+u32 usb_ctrl;
-+#endif
-+      /*
-+       * store current hcd state for otg;
-+       * have_hcd is true when host drv al already part of otg framework,
-+       * otherwise false;
-+       * hcd_add is true when otg framework wants to add host
-+       * drv as part of otg;flase when it wants to remove it
-+       */
-+unsigned have_hcd:1;
-+unsigned hcd_add:1;
-+};
-+
-+static strut ehci_fsl *hcd_to_ehci_fsl(struct usb_hcd *hcd)
-+{
-+struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-+
-+return container_of(ehci, struct ehci_fsl, ehci);
-+}
-+
 +#if defined(CONFIG_FSL_USB2_OTG) || defined(CONFIG_FSL_USB2_OTG_MODULE)
 +static void do_change_hcd(struct work_struct *work)
 +{
-+struct ehci_hcd *ehci = container_of(work, struct ehci_hcd,
-+change_hcd_work);
-+struct usb_hcd *hcd = ehci_to_hcd(ehci);
-+struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
-+void __iomem *non_ehci = hcd->regs;
-+int retval;
++      struct ehci_hcd *ehci = container_of(work, struct ehci_hcd,
++                      change_hcd_work);
++      struct usb_hcd *hcd = ehci_to_hcd(ehci);
++      struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
++      void __iomem *non_ehci = hcd->regs;
++      int retval;
 +
-+if (ehci_fsl->hcd_add && !ehci_fsl->have_hcd) {
-+writel(USBMODE_CM_HOST, non_ehci + FSL_SOC_USB_USBMODE);
-+/* host, gadget and otg share same int line */
-+retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
-+if (retval == 0)
-+ehci_fsl->have_hcd = 1;
-+} else if (!ehci_fsl->hcd_add && ehci_fsl->have_hcd) {
-+      usb_remove_hcd(hcd);
-+ehci_fsl->have_hcd = 0;
-+}
++      if (ehci_fsl->hcd_add && !ehci_fsl->have_hcd) {
++              writel(USBMODE_CM_HOST, non_ehci + FSL_SOC_USB_USBMODE);
++              /* host, gadget and otg share same int line */
++              retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
++              if (retval == 0)
++                      ehci_fsl->have_hcd = 1;
++      } else if (!ehci_fsl->hcd_add && ehci_fsl->have_hcd) {
++              usb_remove_hcd(hcd);
++              ehci_fsl->have_hcd = 0;
++      }
 +}
 +#endif
++
  /* configure so an HC device and id are always provided */
  /* always called with process context; sleeping is OK */
-@@ -131,6 +259,12 @@ static int fsl_ehci_drv_probe(struct pla
+@@ -131,6 +243,12 @@ static int fsl_ehci_drv_probe(struct pla
                clrsetbits_be32(hcd->regs + FSL_SOC_USB_CTRL,
                                CONTROL_REGISTER_W1C_MASK, 0x4);
  
@@ -956,7 +1076,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
        /*
         * Enable UTMI phy and program PTS field in UTMI mode before asserting
         * controller reset for USB Controller version 2.5
-@@ -143,16 +277,20 @@ static int fsl_ehci_drv_probe(struct pla
+@@ -143,16 +261,20 @@ static int fsl_ehci_drv_probe(struct pla
  
        /* Don't need to set host mode here. It will be done by tdi_reset() */
  
@@ -979,7 +1099,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
                dev_dbg(&pdev->dev, "hcd=0x%p  ehci=0x%p, phy=0x%p\n",
                        hcd, ehci, hcd->usb_phy);
  
-@@ -168,6 +306,11 @@ static int fsl_ehci_drv_probe(struct pla
+@@ -168,6 +290,11 @@ static int fsl_ehci_drv_probe(struct pla
                        retval = -ENODEV;
                        goto err2;
                }
@@ -991,17 +1111,16 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
        }
  #endif
        return retval;
-@@ -181,6 +324,18 @@ static int fsl_ehci_drv_probe(struct pla
+@@ -181,6 +308,17 @@ static int fsl_ehci_drv_probe(struct pla
        return retval;
  }
  
-+static bool usb_phy_clk_valid(struct usb_hcd *hcd,
-+                      enum fsl_usb2_phy_modes phy_mode)
++static bool usb_phy_clk_valid(struct usb_hcd *hcd)
 +{
 +      void __iomem *non_ehci = hcd->regs;
 +      bool ret = true;
 +
-+      if (!(in_be32(non_ehci + FSL_SOC_USB_CTRL) & PHY_CLK_VALID))
++      if (!(ioread32be(non_ehci + FSL_SOC_USB_CTRL) & PHY_CLK_VALID))
 +              ret = false;
 +
 +      return ret;
@@ -1010,7 +1129,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
  static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
                               enum fsl_usb2_phy_modes phy_mode,
                               unsigned int port_offset)
-@@ -219,6 +374,21 @@ static int ehci_fsl_setup_phy(struct usb
+@@ -219,6 +357,21 @@ static int ehci_fsl_setup_phy(struct usb
                /* fall through */
        case FSL_USB2_PHY_UTMI:
        case FSL_USB2_PHY_UTMI_DUAL:
@@ -1032,7 +1151,16 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
                if (pdata->have_sysif_regs && pdata->controller_ver) {
                        /* controller version 1.6 or above */
                        clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL,
-@@ -292,14 +462,9 @@ static int ehci_fsl_usb_setup(struct ehc
+@@ -286,20 +439,18 @@ static int ehci_fsl_usb_setup(struct ehc
+       if (pdata->has_fsl_erratum_a005275 == 1)
+               ehci->has_fsl_hs_errata = 1;
++      if (pdata->has_fsl_erratum_a005697 == 1)
++              ehci->has_fsl_susp_errata = 1;
++
+       if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
+                       (pdata->operating_mode == FSL_USB2_DR_OTG))
+               if (ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0))
                        return -EINVAL;
  
        if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
@@ -1048,7 +1176,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
                        ehci->has_fsl_port_bug = 1;
  
                if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
-@@ -379,16 +544,57 @@ static int ehci_fsl_setup(struct usb_hcd
+@@ -379,16 +530,57 @@ static int ehci_fsl_setup(struct usb_hcd
        return retval;
  }
  
@@ -1113,7 +1241,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
  
  #ifdef CONFIG_PPC_MPC512x
  static int ehci_fsl_mpc512x_drv_suspend(struct device *dev)
-@@ -535,26 +741,43 @@ static inline int ehci_fsl_mpc512x_drv_r
+@@ -535,26 +727,45 @@ static inline int ehci_fsl_mpc512x_drv_r
  }
  #endif /* CONFIG_PPC_MPC512x */
  
@@ -1135,7 +1263,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
 +
 +#ifdef CONFIG_PPC
 +suspend_state_t pm_state;
-+pm_state = pm_suspend_state();
++/* FIXME:Need to port fsl_pm.h before enable below code. */
++/*pm_state = pm_suspend_state();*/
++pm_state = PM_SUSPEND_MEM;
 +
 +if (pm_state == PM_SUSPEND_MEM)
 +      ehci_fsl_save_context(hcd);
@@ -1164,7 +1294,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
        if (!fsl_deep_sleep())
                return 0;
  
-@@ -568,12 +791,34 @@ static int ehci_fsl_drv_resume(struct de
+@@ -568,12 +779,36 @@ static int ehci_fsl_drv_resume(struct de
        struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
        void __iomem *non_ehci = hcd->regs;
@@ -1174,7 +1304,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
 +
 +#ifdef CONFIG_PPC
 +suspend_state_t pm_state;
-+pm_state = pm_suspend_state();
++/* FIXME:Need to port fsl_pm.h before enable below code.*/
++/* pm_state = pm_suspend_state(); */
++pm_state = PM_SUSPEND_MEM;
 +
 +if (pm_state == PM_SUSPEND_MEM)
 +      ehci_fsl_restore_context(hcd);
@@ -1211,7 +1343,16 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
  #endif                                /* _EHCI_FSL_H */
 --- a/drivers/usb/host/ehci-hub.c
 +++ b/drivers/usb/host/ehci-hub.c
-@@ -305,6 +305,8 @@ static int ehci_bus_suspend (struct usb_
+@@ -278,6 +278,8 @@ static int ehci_bus_suspend (struct usb_
+               else if ((t1 & PORT_PE) && !(t1 & PORT_SUSPEND)) {
+                       t2 |= PORT_SUSPEND;
+                       set_bit(port, &ehci->bus_suspended);
++                      if (ehci_has_fsl_susp_errata(ehci))
++                              usleep_range(10000, 20000);
+               }
+               /* enable remote wakeup on all ports, if told to do so */
+@@ -305,6 +307,8 @@ static int ehci_bus_suspend (struct usb_
                                                USB_PORT_STAT_HIGH_SPEED)
                                fs_idle_delay = true;
                        ehci_writel(ehci, t2, reg);
@@ -1232,8 +1373,21 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
  
        /* list of itds & sitds completed while now_frame was still active */
        struct list_head        cached_itd_list;
-@@ -706,8 +709,10 @@ ehci_port_speed(struct ehci_hcd *ehci, u
+@@ -219,6 +222,7 @@ struct ehci_hcd {                  /* one per controlle
+       unsigned                no_selective_suspend:1;
+       unsigned                has_fsl_port_bug:1; /* FreeScale */
+       unsigned                has_fsl_hs_errata:1;    /* Freescale HS quirk */
++      unsigned                has_fsl_susp_errata:1; /*Freescale SUSP quirk*/
+       unsigned                big_endian_mmio:1;
+       unsigned                big_endian_desc:1;
+       unsigned                big_endian_capbase:1;
+@@ -704,10 +708,15 @@ ehci_port_speed(struct ehci_hcd *ehci, u
+ #if defined(CONFIG_PPC_85xx)
+ /* Some Freescale processors have an erratum (USB A-005275) in which
   * incoming packets get corrupted in HS mode
++ * Some Freescale processors have an erratum (USB A-005697) in which
++ * we need to wait for 10ms for bus to fo into suspend mode after
++ * setting SUSP bit
   */
  #define ehci_has_fsl_hs_errata(e)     ((e)->has_fsl_hs_errata)
 +#define ehci_has_fsl_susp_errata(e)     ((e)->has_fsl_susp_errata)
@@ -1264,6 +1418,149 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
  
        /*
         * Determine whether phy_clk_valid needs to be checked
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -223,6 +223,16 @@ static int xhci_plat_probe(struct platfo
+       if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable"))
+               xhci->quirks |= XHCI_LPM_SUPPORT;
++      if (device_property_read_bool(&pdev->dev, "quirk-reverse-in-out"))
++              xhci->quirks |= XHCI_REVERSE_IN_OUT;
++
++      if (device_property_read_bool(&pdev->dev,
++                              "quirk-stop-transfer-in-block"))
++              xhci->quirks |= XHCI_STOP_TRANSFER_IN_BLOCK;
++
++      if (device_property_read_bool(&pdev->dev, "quirk-stop-ep-in-u1"))
++              xhci->quirks |= XHCI_STOP_EP_IN_U1;
++
+       if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped"))
+               xhci->quirks |= XHCI_BROKEN_PORT_PED;
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1852,14 +1852,17 @@ static int finish_td(struct xhci_hcd *xh
+       union xhci_trb *event_trb, struct xhci_transfer_event *event,
+       struct xhci_virt_ep *ep, int *status, bool skip)
+ {
++      struct xhci_dequeue_state deq_state;
+       struct xhci_virt_device *xdev;
+       struct xhci_ring *ep_ring;
++      unsigned int stream_id;
+       unsigned int slot_id;
+       int ep_index;
+       struct urb *urb = NULL;
+       struct xhci_ep_ctx *ep_ctx;
+       int ret = 0;
+       struct urb_priv *urb_priv;
++      u32 remaining;
+       u32 trb_comp_code;
+       slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
+@@ -1885,13 +1888,29 @@ static int finish_td(struct xhci_hcd *xh
+       if (trb_comp_code == COMP_STALL ||
+               xhci_requires_manual_halt_cleanup(xhci, ep_ctx,
+                                               trb_comp_code)) {
+-              /* Issue a reset endpoint command to clear the host side
+-               * halt, followed by a set dequeue command to move the
+-               * dequeue pointer past the TD.
+-               * The class driver clears the device side halt later.
++              /*
++               * A-007463: After transaction error, controller switches
++               * control transfer data stage from IN to OUT direction.
+                */
+-              xhci_cleanup_halted_endpoint(xhci, slot_id, ep_index,
++              remaining = EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
++              if (remaining && xhci_requires_manual_halt_cleanup(xhci, ep_ctx,
++                                      trb_comp_code) &&
++                                      (xhci->quirks & XHCI_REVERSE_IN_OUT)) {
++                      memset(&deq_state, 0, sizeof(deq_state));
++                      xhci_find_new_dequeue_state(xhci, slot_id,
++                              ep_index, td->urb->stream_id, td, &deq_state);
++                      xhci_queue_new_dequeue_state(xhci, slot_id, ep_index,
++                                                      stream_id, &deq_state);
++                      xhci_ring_cmd_db(xhci);
++              } else {
++                      /* Issue a reset endpoint command to clear the host side
++                       * halt, followed by a set dequeue command to move the
++                       * dequeue pointer past the TD.
++                       * The class driver clears the device side halt later.
++                       */
++                      xhci_cleanup_halted_endpoint(xhci, slot_id, ep_index,
+                                       ep_ring->stream_id, td, event_trb);
++              }
+       } else {
+               /* Update ring dequeue pointer */
+               while (ep_ring->dequeue != td->last_trb)
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -1604,14 +1604,38 @@ int xhci_urb_dequeue(struct usb_hcd *hcd
+                       ret = -ENOMEM;
+                       goto done;
+               }
+-              ep->ep_state |= EP_HALT_PENDING;
+-              ep->stop_cmds_pending++;
+-              ep->stop_cmd_timer.expires = jiffies +
++              /*
++               *A-009611: Issuing an End Transfer command on an IN endpoint.
++               *when a transfer is in progress on USB blocks the transmission
++               *Workaround: Software must wait for all existing TRBs to
++               *complete before issuing End transfer command.
++               */
++              if ((ep_ring->enqueue == ep_ring->dequeue &&
++                              (xhci->quirks & XHCI_STOP_TRANSFER_IN_BLOCK)) ||
++                              !(xhci->quirks & XHCI_STOP_TRANSFER_IN_BLOCK)) {
++                      ep->ep_state |= EP_HALT_PENDING;
++                      ep->stop_cmds_pending++;
++                      ep->stop_cmd_timer.expires = jiffies +
+                       XHCI_STOP_EP_CMD_TIMEOUT * HZ;
+-              add_timer(&ep->stop_cmd_timer);
+-              xhci_queue_stop_endpoint(xhci, command, urb->dev->slot_id,
+-                                       ep_index, 0);
+-              xhci_ring_cmd_db(xhci);
++                      add_timer(&ep->stop_cmd_timer);
++                      xhci_queue_stop_endpoint(xhci, command,
++                                      urb->dev->slot_id,
++                                      ep_index, 0);
++                      xhci_ring_cmd_db(xhci);
++              }
++
++              /*
++               *A-009668: Stop Endpoint Command does not complete.
++               *Workaround: Instead of issuing a Stop Endpoint Command,
++               *issue a Disable Slot Command with the corresponding slot ID.
++               *Alternately, you can issue an Address Device Command with
++               *BSR=1
++               */
++              if ((urb->dev->speed <= USB_SPEED_HIGH) &&
++                                      (xhci->quirks & XHCI_STOP_EP_IN_U1)) {
++                      xhci_queue_slot_control(xhci, command, TRB_DISABLE_SLOT,
++                                      urb->dev->slot_id);
++              }
+       }
+ done:
+       spin_unlock_irqrestore(&xhci->lock, flags);
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1625,7 +1625,7 @@ struct xhci_hcd {
+ #define XHCI_STATE_REMOVING   (1 << 2)
+       /* Statistics */
+       int                     error_bitmask;
+-      unsigned int            quirks;
++      u64                     quirks;
+ #define       XHCI_LINK_TRB_QUIRK     (1 << 0)
+ #define XHCI_RESET_EP_QUIRK   (1 << 1)
+ #define XHCI_NEC_HOST         (1 << 2)
+@@ -1661,6 +1661,9 @@ struct xhci_hcd {
+ #define XHCI_SSIC_PORT_UNUSED (1 << 22)
+ #define XHCI_NO_64BIT_SUPPORT (1 << 23)
+ #define XHCI_MISSING_CAS      (1 << 24)
++#define XHCI_REVERSE_IN_OUT    (1 << 29)
++#define XHCI_STOP_TRANSFER_IN_BLOCK    (1 << 30)
++#define XHCI_STOP_EP_IN_U1    (1 << 31)
+ /* For controller with a broken Port Disable implementation */
+ #define XHCI_BROKEN_PORT_PED  (1 << 25)
+ #define XHCI_LIMIT_ENDPOINT_INTERVAL_7        (1 << 26)
 --- a/drivers/usb/phy/phy-fsl-usb.c
 +++ b/drivers/usb/phy/phy-fsl-usb.c
 @@ -1,5 +1,5 @@