diff options
author | Yangbo Lu <yangbo.lu@nxp.com> | 2018-02-06 12:39:05 +0800 |
---|---|---|
committer | John Crispin <john@phrozen.org> | 2018-02-13 10:01:49 +0100 |
commit | 1a28100e68f4863ebc68625d5c6123ef0e5de8db (patch) | |
tree | 904bf6eec64dd2235c89e02bdc4033253512fbd1 /target/linux/layerscape/patches-4.9/817-usb-support-layerscape.patch | |
parent | 3a0fa1e7b860c600256f102d07356964821e7d7e (diff) | |
download | upstream-1a28100e68f4863ebc68625d5c6123ef0e5de8db.tar.gz upstream-1a28100e68f4863ebc68625d5c6123ef0e5de8db.tar.bz2 upstream-1a28100e68f4863ebc68625d5c6123ef0e5de8db.zip |
layerscape: update patches-4.9 to LSDK1712
Patches changes
- Updated patches-4.9 to NXP LSDK1712 linux-4.9.
- Merged changes of patch 303 into integrated patch 201.
- Split changes of patch 706 into dpaa part and dpaa2
part, and merged these changes into integrated patches
701 and 705.
- Removed patch 819 since ehci-fsl driver could be compiled now.
- Refreshed these patches.
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
Diffstat (limited to 'target/linux/layerscape/patches-4.9/817-usb-support-layerscape.patch')
-rw-r--r-- | target/linux/layerscape/patches-4.9/817-usb-support-layerscape.patch | 467 |
1 files changed, 375 insertions, 92 deletions
diff --git a/target/linux/layerscape/patches-4.9/817-usb-support-layerscape.patch b/target/linux/layerscape/patches-4.9/817-usb-support-layerscape.patch index 2e7885a694..e199a4f498 100644 --- a/target/linux/layerscape/patches-4.9/817-usb-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.9/817-usb-support-layerscape.patch @@ -1,9 +1,9 @@ -From b14460ee524a34d3b94b44032b52155c4cd708e5 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,29 +15,68 @@ 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/r8152.c | 4 + + 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 | 5 + + 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 + - 18 files changed, 730 insertions(+), 73 deletions(-) + 25 files changed, 836 insertions(+), 88 deletions(-) +--- a/drivers/net/usb/cdc_ether.c ++++ b/drivers/net/usb/cdc_ether.c +@@ -532,6 +532,7 @@ static const struct driver_info wwan_inf + #define LENOVO_VENDOR_ID 0x17ef + #define NVIDIA_VENDOR_ID 0x0955 + #define HP_VENDOR_ID 0x03f0 ++#define TPLINK_VENDOR_ID 0x2357 + + static const struct usb_device_id products[] = { + /* BLACKLIST !! +@@ -732,6 +733,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 -@@ -1816,6 +1816,10 @@ static int rx_bottom(struct r8152 *tp, i +@@ -520,6 +520,7 @@ enum rtl8152_flags { + #define VENDOR_ID_SAMSUNG 0x04e8 + #define VENDOR_ID_LENOVO 0x17ef + #define VENDOR_ID_NVIDIA 0x0955 ++#define VENDOR_ID_TPLINK 0x2357 + + #define MCU_TYPE_PLA 0x0100 + #define MCU_TYPE_USB 0x0000 +@@ -1816,6 +1817,10 @@ static int rx_bottom(struct r8152 *tp, i unsigned int pkt_len; struct sk_buff *skb; @@ -48,6 +87,14 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK; if (pkt_len < ETH_ZLEN) break; +@@ -4507,6 +4512,7 @@ static struct usb_device_id rtl8152_tabl + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)}, + {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[] @@ -280,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 +@@ -919,11 +1034,117 @@ static void dwc3_core_exit_mode(struct d } } @@ -325,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"); + @@ -365,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", @@ -390,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 +@@ -955,6 +1176,11 @@ static int dwc3_probe(struct platform_de dwc->xhci_resources[0].flags = res->flags; dwc->xhci_resources[0].name = res->name; @@ -402,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 +@@ -997,6 +1223,12 @@ static int dwc3_probe(struct platform_de dwc->usb3_lpm_capable = device_property_read_bool(dev, "snps,usb3_lpm_capable"); @@ -415,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 +@@ -1041,6 +1273,8 @@ static int dwc3_probe(struct platform_de dwc->hird_threshold = hird_threshold | (dwc->is_utmi_l1_suspend << 4); @@ -424,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 +@@ -1064,6 +1298,11 @@ static int dwc3_probe(struct platform_de if (ret < 0) goto err1; @@ -506,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 { +@@ -829,6 +860,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; +@@ -847,6 +879,7 @@ struct dwc3 { spinlock_t lock; struct device *dev; @@ -514,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 { +@@ -872,6 +905,12 @@ struct dwc3 { enum usb_phy_interface hsphy_mode; u32 fladj; @@ -527,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 { +@@ -948,9 +987,12 @@ struct dwc3 { unsigned ep0_bounced:1; unsigned ep0_expect_in:1; unsigned has_hibernation:1; @@ -540,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 { +@@ -971,9 +1013,16 @@ struct dwc3 { unsigned dis_rxdet_inp3_quirk:1; unsigned dis_u2_freeclk_exists_quirk:1; unsigned dis_del_phy_power_chg_quirk:1; @@ -548,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 +@@ -2930,6 +2930,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"); +@@ -3044,6 +3045,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 @@ @@ -588,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) @@ -815,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" @@ -864,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; +}; @@ -897,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; @@ -905,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); @@ -970,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() */ @@ -993,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; } @@ -1005,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; @@ -1024,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: @@ -1046,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) { @@ -1062,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; } @@ -1127,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 */ @@ -1149,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); @@ -1178,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; @@ -1188,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); @@ -1225,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); @@ -1246,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) @@ -1278,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 +@@ -1570,14 +1570,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 +@@ -1621,7 +1621,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) +@@ -1657,6 +1657,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 @@ |