ipq806x: switch to upstream usb driver and backport fixes
authorPavel Kubelun <be.dissent@gmail.com>
Sat, 12 Nov 2016 11:35:56 +0000 (14:35 +0300)
committerJohn Crispin <john@phrozen.org>
Mon, 21 Nov 2016 08:58:42 +0000 (09:58 +0100)
Also removing fifo-resize property drom DT as it has been removed from the driver.

Signed-off-by: Pavel Kubelun <be.dissent@gmail.com>
21 files changed:
target/linux/ipq806x/Makefile
target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8065.dtsi
target/linux/ipq806x/modules.mk
target/linux/ipq806x/patches-4.4/096-01-usb-dwc3-core-purge-dev_dbg-calls.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/096-02-usb-dwc3-Update-maximum_speed-for-SuperSpeedPlus.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/096-03-usb-dwc3-Validate-the-maximum_speed-parameter.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/096-04-usb-dwc3-DWC_usb31-controller-check.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/096-05-usb-dwc3-Update-register-fields-for-SuperSpeedPlus.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/096-06-usb-dwc3-core-improve-reset-sequence.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/096-07-usb-dwc3-drop-FIFO-resizing-logic.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/096-08-usb-dwc3-remove-num_event_buffers.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/096-09-usb-dwc3-drop-ev_buffs-array.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/096-10-usb-dwc3-core-fix-PHY-handling-during-suspend.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/097-1-usb-dwc3-add-generic-OF-glue-layer.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/097-2-usb-dwc3-of-simple-fix-build-warning-on-PM.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/097-3-usb-dwc3-Remove-impossible-check-for-of_clk_get_pare.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/097-4-usb-dwc3-fix-missing-platform_set_drvdata-in-dwc3_of_simple_probe.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.4/097-usb-dwc3-add-generic-OF-glue-layer.patch [deleted file]
target/linux/ipq806x/patches-4.4/098-usb-dwc3-of-simple-fix-build-warning-on-PM.patch [deleted file]
target/linux/ipq806x/patches-4.4/099-usb-dwc3-Remove-impossible-check-for-of_clk_get_pare.patch [deleted file]
target/linux/ipq806x/patches-4.4/101-ARM-qcom-add-USB-nodes-to-ipq806x-ap148.patch

index 27ad6a4..3a65d33 100644 (file)
@@ -19,7 +19,7 @@ DEFAULT_PACKAGES += \
        kmod-leds-gpio kmod-gpio-button-hotplug swconfig \
        kmod-ata-core kmod-ata-ahci kmod-ata-ahci-platform \
        kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport \
-       kmod-usb3 kmod-usb-dwc3-qcom kmod-usb-phy-qcom-dwc3 \
+       kmod-usb3 kmod-usb-dwc3-of-simple kmod-usb-phy-qcom-dwc3 \
        kmod-ath10k wpad-mini \
        uboot-envtools
 
index 435692b..e0ba99a 100644 (file)
                                interrupts = <0 110 0x4>;
                                phys = <&hs_phy_0>, <&ss_phy_0>;
                                phy-names = "usb2-phy", "usb3-phy";
-                               tx-fifo-resize;
                                dr_mode = "host";
                        };
                };
                                interrupts = <0 205 0x4>;
                                phys = <&hs_phy_1>, <&ss_phy_1>;
                                phy-names = "usb2-phy", "usb3-phy";
-                               tx-fifo-resize;
                                dr_mode = "host";
                        };
                };
index 38dd195..6f1ca2d 100644 (file)
@@ -29,20 +29,3 @@ define KernelPackage/usb-phy-qcom-dwc3/description
 endef
 
 $(eval $(call KernelPackage,usb-phy-qcom-dwc3))
-
-
-define KernelPackage/usb-dwc3-qcom
-  TITLE:=DWC3 USB QCOM controller driver
-  DEPENDS:=@TARGET_ipq806x +kmod-usb-dwc3 +kmod-usb-phy-qcom-dwc3
-  KCONFIG:= CONFIG_USB_DWC3_QCOM
-  FILES:= $(LINUX_DIR)/drivers/usb/dwc3/dwc3-qcom.ko
-  AUTOLOAD:=$(call AutoLoad,53,dwc3-qcom,1)
-  $(call AddDepends/usb)
-endef
-
-define KernelPackage/usb-dwc3-qcom/description
- This driver provides support for the integrated DesignWare
- USB3 IP Core within the QCOM SoCs.
-endef
-
-$(eval $(call KernelPackage,usb-dwc3-qcom))
diff --git a/target/linux/ipq806x/patches-4.4/096-01-usb-dwc3-core-purge-dev_dbg-calls.patch b/target/linux/ipq806x/patches-4.4/096-01-usb-dwc3-core-purge-dev_dbg-calls.patch
new file mode 100644 (file)
index 0000000..b940827
--- /dev/null
@@ -0,0 +1,46 @@
+From 1407bf13e3bf5f1168484c3e68b6ef9d8cf2bc72 Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <balbi@ti.com>
+Date: Mon, 16 Nov 2015 16:06:37 -0600
+Subject: usb: dwc3: core: purge dev_dbg() calls
+
+The last few dev_dbg() messages are converted to
+tracepoints and we can finally ignore dev_dbg()
+messages during debug sessions.
+
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+---
+ drivers/usb/dwc3/core.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 22b47973..de5e01f 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -272,7 +272,8 @@ static int dwc3_event_buffers_setup(struct dwc3 *dwc)
+       for (n = 0; n < dwc->num_event_buffers; n++) {
+               evt = dwc->ev_buffs[n];
+-              dev_dbg(dwc->dev, "Event buf %p dma %08llx length %d\n",
++              dwc3_trace(trace_dwc3_core,
++                              "Event buf %p dma %08llx length %d\n",
+                               evt->buf, (unsigned long long) evt->dma,
+                               evt->length);
+@@ -608,12 +609,13 @@ static int dwc3_core_init(struct dwc3 *dwc)
+               reg |= DWC3_GCTL_GBLHIBERNATIONEN;
+               break;
+       default:
+-              dev_dbg(dwc->dev, "No power optimization available\n");
++              dwc3_trace(trace_dwc3_core, "No power optimization available\n");
+       }
+       /* check if current dwc3 is on simulation board */
+       if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) {
+-              dev_dbg(dwc->dev, "it is on FPGA board\n");
++              dwc3_trace(trace_dwc3_core,
++                              "running on FPGA platform\n");
+               dwc->is_fpga = true;
+       }
+-- 
+cgit v0.12
diff --git a/target/linux/ipq806x/patches-4.4/096-02-usb-dwc3-Update-maximum_speed-for-SuperSpeedPlus.patch b/target/linux/ipq806x/patches-4.4/096-02-usb-dwc3-Update-maximum_speed-for-SuperSpeedPlus.patch
new file mode 100644 (file)
index 0000000..9575166
--- /dev/null
@@ -0,0 +1,56 @@
+From 2c7f1bd9127a1a49ee25d9c2b2ce17b11c7fb05f Mon Sep 17 00:00:00 2001
+From: John Youn <John.Youn@synopsys.com>
+Date: Fri, 5 Feb 2016 17:08:59 -0800
+Subject: usb: dwc3: Update maximum_speed for SuperSpeedPlus
+
+If the maximum_speed is not set, set it to a known value, either
+SuperSpeed or SuperSpeedPlus based on the type of controller we are
+using. If we are on DWC_usb31 controller, check the PHY interface to see
+if it is capable of SuperSpeedPlus.
+
+Also this check is moved after dwc3_core_init() so that we can check
+dwc->revision.
+
+Signed-off-by: John Youn <johnyoun@synopsys.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+---
+ drivers/usb/dwc3/core.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index de5e01f..001c755 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -962,10 +962,6 @@ static int dwc3_probe(struct platform_device *pdev)
+               fladj = pdata->fladj_value;
+       }
+-      /* default to superspeed if no maximum_speed passed */
+-      if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
+-              dwc->maximum_speed = USB_SPEED_SUPER;
+-
+       dwc->lpm_nyet_threshold = lpm_nyet_threshold;
+       dwc->tx_de_emphasis = tx_de_emphasis;
+@@ -1016,6 +1012,19 @@ static int dwc3_probe(struct platform_device *pdev)
+               goto err1;
+       }
++      /* default to superspeed if no maximum_speed passed */
++      if (dwc->maximum_speed == USB_SPEED_UNKNOWN) {
++              dwc->maximum_speed = USB_SPEED_SUPER;
++
++              /*
++               * default to superspeed plus if we are capable.
++               */
++              if (dwc3_is_usb31(dwc) &&
++                  (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
++                   DWC3_GHWPARAMS3_SSPHY_IFC_GEN2))
++                      dwc->maximum_speed = USB_SPEED_SUPER_PLUS;
++      }
++
+       /* Adjust Frame Length */
+       dwc3_frame_length_adjustment(dwc, fladj);
+-- 
+cgit v0.12
diff --git a/target/linux/ipq806x/patches-4.4/096-03-usb-dwc3-Validate-the-maximum_speed-parameter.patch b/target/linux/ipq806x/patches-4.4/096-03-usb-dwc3-Validate-the-maximum_speed-parameter.patch
new file mode 100644 (file)
index 0000000..4382126
--- /dev/null
@@ -0,0 +1,74 @@
+From 77966eb85e6d988a6daaf8ac14ac33026ceb3ab7 Mon Sep 17 00:00:00 2001
+From: John Youn <John.Youn@synopsys.com>
+Date: Fri, 19 Feb 2016 17:31:01 -0800
+Subject: usb: dwc3: Validate the maximum_speed parameter
+
+Check that dwc->maximum_speed is set to a valid value. Also add an error
+when we use it later if we encounter an invalid value.
+
+Signed-off-by: John Youn <johnyoun@synopsys.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+---
+ drivers/usb/dwc3/core.c   | 18 ++++++++++++++++--
+ drivers/usb/dwc3/gadget.c |  9 ++++++---
+ 2 files changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 001c755..17fd814 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -1012,8 +1012,20 @@ static int dwc3_probe(struct platform_device *pdev)
+               goto err1;
+       }
+-      /* default to superspeed if no maximum_speed passed */
+-      if (dwc->maximum_speed == USB_SPEED_UNKNOWN) {
++      /* Check the maximum_speed parameter */
++      switch (dwc->maximum_speed) {
++      case USB_SPEED_LOW:
++      case USB_SPEED_FULL:
++      case USB_SPEED_HIGH:
++      case USB_SPEED_SUPER:
++      case USB_SPEED_SUPER_PLUS:
++              break;
++      default:
++              dev_err(dev, "invalid maximum_speed parameter %d\n",
++                      dwc->maximum_speed);
++              /* fall through */
++      case USB_SPEED_UNKNOWN:
++              /* default to superspeed */
+               dwc->maximum_speed = USB_SPEED_SUPER;
+               /*
+@@ -1023,6 +1035,8 @@ static int dwc3_probe(struct platform_device *pdev)
+                   (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
+                    DWC3_GHWPARAMS3_SSPHY_IFC_GEN2))
+                       dwc->maximum_speed = USB_SPEED_SUPER_PLUS;
++
++              break;
+       }
+       /* Adjust Frame Length */
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 482e6a1..3ac170f 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1670,10 +1670,13 @@ static int dwc3_gadget_start(struct usb_gadget *g,
+               case USB_SPEED_SUPER_PLUS:
+                       reg |= DWC3_DSTS_SUPERSPEED_PLUS;
+                       break;
+-              case USB_SPEED_SUPER:   /* FALLTHROUGH */
+-              case USB_SPEED_UNKNOWN: /* FALTHROUGH */
+               default:
+-                      reg |= DWC3_DSTS_SUPERSPEED;
++                      dev_err(dwc->dev, "invalid dwc->maximum_speed (%d)\n",
++                              dwc->maximum_speed);
++                      /* fall through */
++              case USB_SPEED_SUPER:
++                      reg |= DWC3_DCFG_SUPERSPEED;
++                      break;
+               }
+       }
+       dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+-- 
+cgit v0.12
diff --git a/target/linux/ipq806x/patches-4.4/096-04-usb-dwc3-DWC_usb31-controller-check.patch b/target/linux/ipq806x/patches-4.4/096-04-usb-dwc3-DWC_usb31-controller-check.patch
new file mode 100644 (file)
index 0000000..47278d4
--- /dev/null
@@ -0,0 +1,32 @@
+From c4137a9c841ec7fb300782d211f2d6907f4d6e20 Mon Sep 17 00:00:00 2001
+From: John Youn <John.Youn@synopsys.com>
+Date: Fri, 5 Feb 2016 17:08:18 -0800
+Subject: usb: dwc3: DWC_usb31 controller check
+
+Add a convenience function to check if the controller is DWC_usb31.
+
+Signed-off-by: John Youn <johnyoun@synopsys.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+---
+ drivers/usb/dwc3/core.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
+index e4f8b90..c0520d67 100644
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -1024,6 +1024,12 @@ struct dwc3_gadget_ep_cmd_params {
+ void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
+ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);
++/* check whether we are on the DWC_usb31 core */
++static inline bool dwc3_is_usb31(struct dwc3 *dwc)
++{
++      return !!(dwc->revision & DWC3_REVISION_IS_DWC31);
++}
++
+ #if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
+ int dwc3_host_init(struct dwc3 *dwc);
+ void dwc3_host_exit(struct dwc3 *dwc);
+-- 
+cgit v0.12
diff --git a/target/linux/ipq806x/patches-4.4/096-05-usb-dwc3-Update-register-fields-for-SuperSpeedPlus.patch b/target/linux/ipq806x/patches-4.4/096-05-usb-dwc3-Update-register-fields-for-SuperSpeedPlus.patch
new file mode 100644 (file)
index 0000000..e4805db
--- /dev/null
@@ -0,0 +1,46 @@
+From 1f38f88a24c86d46cf47782ffabd5457f231f8ca Mon Sep 17 00:00:00 2001
+From: John Youn <John.Youn@synopsys.com>
+Date: Fri, 5 Feb 2016 17:08:31 -0800
+Subject: usb: dwc3: Update register fields for SuperSpeedPlus
+
+Update various registers fields definitions for the DWC_usb31 controller
+for SuperSpeedPlus support.
+
+Signed-off-by: John Youn <johnyoun@synopsys.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+---
+ drivers/usb/dwc3/core.h | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
+index c0520d67..6254b2f 100644
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -223,7 +223,8 @@
+ /* Global HWPARAMS3 Register */
+ #define DWC3_GHWPARAMS3_SSPHY_IFC(n)          ((n) & 3)
+ #define DWC3_GHWPARAMS3_SSPHY_IFC_DIS         0
+-#define DWC3_GHWPARAMS3_SSPHY_IFC_ENA         1
++#define DWC3_GHWPARAMS3_SSPHY_IFC_GEN1                1
++#define DWC3_GHWPARAMS3_SSPHY_IFC_GEN2                2 /* DWC_usb31 only */
+ #define DWC3_GHWPARAMS3_HSPHY_IFC(n)          (((n) & (3 << 2)) >> 2)
+ #define DWC3_GHWPARAMS3_HSPHY_IFC_DIS         0
+ #define DWC3_GHWPARAMS3_HSPHY_IFC_UTMI                1
+@@ -249,6 +250,7 @@
+ #define DWC3_DCFG_DEVADDR_MASK        DWC3_DCFG_DEVADDR(0x7f)
+ #define DWC3_DCFG_SPEED_MASK  (7 << 0)
++#define DWC3_DCFG_SUPERSPEED_PLUS (5 << 0)  /* DWC_usb31 only */
+ #define DWC3_DCFG_SUPERSPEED  (4 << 0)
+ #define DWC3_DCFG_HIGHSPEED   (0 << 0)
+ #define DWC3_DCFG_FULLSPEED2  (1 << 0)
+@@ -339,6 +341,7 @@
+ #define DWC3_DSTS_CONNECTSPD          (7 << 0)
++#define DWC3_DSTS_SUPERSPEED_PLUS     (5 << 0) /* DWC_usb31 only */
+ #define DWC3_DSTS_SUPERSPEED          (4 << 0)
+ #define DWC3_DSTS_HIGHSPEED           (0 << 0)
+ #define DWC3_DSTS_FULLSPEED2          (1 << 0)
+-- 
+cgit v0.12
diff --git a/target/linux/ipq806x/patches-4.4/096-06-usb-dwc3-core-improve-reset-sequence.patch b/target/linux/ipq806x/patches-4.4/096-06-usb-dwc3-core-improve-reset-sequence.patch
new file mode 100644 (file)
index 0000000..197dd05
--- /dev/null
@@ -0,0 +1,101 @@
+From f59dcab176293b646e1358144c93c58c3cda2813 Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <felipe.balbi@linux.intel.com>
+Date: Fri, 11 Mar 2016 10:51:52 +0200
+Subject: usb: dwc3: core: improve reset sequence
+
+According to Synopsys Databook, we shouldn't be
+relying on GCTL.CORESOFTRESET bit as that's only for
+debugging purposes. Instead, let's use DCTL.CSFTRST
+if we're OTG or PERIPHERAL mode.
+
+Host side block will be reset by XHCI driver if
+necessary. Note that this reduces amount of time
+spent on dwc3_probe() by a long margin.
+
+We're still gonna wait for reset to finish for a
+long time (default to 1ms max), but tests show that
+the reset polling loop executed at most 19 times
+(modprobe dwc3 && modprobe -r dwc3 executed 1000
+times in a row).
+
+Suggested-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/dwc3/core.c | 48 ++++++++++++++++++------------------------------
+ 1 file changed, 18 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 17fd814..fa20f5a9 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -67,23 +67,9 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
+ static int dwc3_core_soft_reset(struct dwc3 *dwc)
+ {
+       u32             reg;
++      int             retries = 1000;
+       int             ret;
+-      /* Before Resetting PHY, put Core in Reset */
+-      reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+-      reg |= DWC3_GCTL_CORESOFTRESET;
+-      dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+-
+-      /* Assert USB3 PHY reset */
+-      reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
+-      reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
+-      dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
+-
+-      /* Assert USB2 PHY reset */
+-      reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+-      reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
+-      dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+-
+       usb_phy_init(dwc->usb2_phy);
+       usb_phy_init(dwc->usb3_phy);
+       ret = phy_init(dwc->usb2_generic_phy);
+@@ -95,26 +81,28 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
+               phy_exit(dwc->usb2_generic_phy);
+               return ret;
+       }
+-      mdelay(100);
+-      /* Clear USB3 PHY reset */
+-      reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
+-      reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
+-      dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
++      /*
++       * We're resetting only the device side because, if we're in host mode,
++       * XHCI driver will reset the host block. If dwc3 was configured for
++       * host-only mode, then we can return early.
++       */
++      if (dwc->dr_mode == USB_DR_MODE_HOST)
++              return 0;
+-      /* Clear USB2 PHY reset */
+-      reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+-      reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
+-      dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
++      reg = dwc3_readl(dwc->regs, DWC3_DCTL);
++      reg |= DWC3_DCTL_CSFTRST;
++      dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+-      mdelay(100);
++      do {
++              reg = dwc3_readl(dwc->regs, DWC3_DCTL);
++              if (!(reg & DWC3_DCTL_CSFTRST))
++                      return 0;
+-      /* After PHYs are stable we can take Core out of reset state */
+-      reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+-      reg &= ~DWC3_GCTL_CORESOFTRESET;
+-      dwc3_writel(dwc->regs, DWC3_GCTL, reg);
++              udelay(1);
++      } while (--retries);
+-      return 0;
++      return -ETIMEDOUT;
+ }
+ /**
+-- 
+cgit v0.12
diff --git a/target/linux/ipq806x/patches-4.4/096-07-usb-dwc3-drop-FIFO-resizing-logic.patch b/target/linux/ipq806x/patches-4.4/096-07-usb-dwc3-drop-FIFO-resizing-logic.patch
new file mode 100644 (file)
index 0000000..9b6026d
--- /dev/null
@@ -0,0 +1,258 @@
+From bc5081617faeb3b2f0c126dc37264b87af7da47f Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <felipe.balbi@linux.intel.com>
+Date: Thu, 4 Feb 2016 14:18:01 +0200
+Subject: usb: dwc3: drop FIFO resizing logic
+
+That FIFO resizing logic was added to support OMAP5
+ES1.0 which had a bogus default FIFO size. I can't
+remember the exact size of default FIFO, but it was
+less than one bulk superspeed packet (<1024) which
+would prevent USB3 from ever working on OMAP5 ES1.0.
+
+However, OMAP5 ES1.0 support has been dropped by
+commit aa2f4b16f830 ("ARM: OMAP5: id: Remove ES1.0
+support") which renders FIFO resizing unnecessary.
+
+Tested-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ Documentation/devicetree/bindings/usb/dwc3.txt     |  4 +-
+ .../devicetree/bindings/usb/qcom,dwc3.txt          |  1 -
+ drivers/usb/dwc3/core.c                            |  4 -
+ drivers/usb/dwc3/core.h                            |  5 --
+ drivers/usb/dwc3/ep0.c                             |  9 ---
+ drivers/usb/dwc3/gadget.c                          | 86 ----------------------
+ drivers/usb/dwc3/platform_data.h                   |  1 -
+ 7 files changed, 2 insertions(+), 108 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
+index fb2ad0a..1569568 100644
+--- a/Documentation/devicetree/bindings/usb/dwc3.txt
++++ b/Documentation/devicetree/bindings/usb/dwc3.txt
+@@ -14,7 +14,6 @@ Optional properties:
+    the second element is expected to be a handle to the USB3/SS PHY
+  - phys: from the *Generic PHY* bindings
+  - phy-names: from the *Generic PHY* bindings
+- - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
+  - snps,usb3_lpm_capable: determines if platform is USB3 LPM capable
+  - snps,disable_scramble_quirk: true when SW should disable data scrambling.
+       Only really useful for FPGA builds.
+@@ -47,6 +46,8 @@ Optional properties:
+       register for post-silicon frame length adjustment when the
+       fladj_30mhz_sdbnd signal is invalid or incorrect.
++ - <DEPRECATED> tx-fifo-resize: determines if the FIFO *has* to be reallocated.
++
+ This is usually a subnode to DWC3 glue to which it is connected.
+ dwc3@4a030000 {
+@@ -54,5 +55,4 @@ dwc3@4a030000 {
+       reg = <0x4a030000 0xcfff>;
+       interrupts = <0 92 4>
+       usb-phy = <&usb2_phy>, <&usb3,phy>;
+-      tx-fifo-resize;
+ };
+diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
+index ca164e7..39acb08 100644
+--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
++++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
+@@ -59,7 +59,6 @@ Example device nodes:
+                               interrupts = <0 205 0x4>;
+                               phys = <&hs_phy>, <&ss_phy>;
+                               phy-names = "usb2-phy", "usb3-phy";
+-                              tx-fifo-resize;
+                               dr_mode = "host";
+                       };
+               };
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index fa20f5a9..67d183a 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -882,9 +882,6 @@ static int dwc3_probe(struct platform_device *pdev)
+       dwc->usb3_lpm_capable = device_property_read_bool(dev,
+                               "snps,usb3_lpm_capable");
+-      dwc->needs_fifo_resize = device_property_read_bool(dev,
+-                              "tx-fifo-resize");
+-
+       dwc->disable_scramble_quirk = device_property_read_bool(dev,
+                               "snps,disable_scramble_quirk");
+       dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
+@@ -926,7 +923,6 @@ static int dwc3_probe(struct platform_device *pdev)
+               if (pdata->hird_threshold)
+                       hird_threshold = pdata->hird_threshold;
+-              dwc->needs_fifo_resize = pdata->tx_fifo_resize;
+               dwc->usb3_lpm_capable = pdata->usb3_lpm_capable;
+               dwc->dr_mode = pdata->dr_mode;
+diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
+index 6254b2f..7cbe9e9 100644
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -709,9 +709,7 @@ struct dwc3_scratchpad_array {
+  *    0       - utmi_sleep_n
+  *    1       - utmi_l1_suspend_n
+  * @is_fpga: true when we are using the FPGA board
+- * @needs_fifo_resize: not all users might want fifo resizing, flag it
+  * @pullups_connected: true when Run/Stop bit is set
+- * @resize_fifos: tells us it's ok to reconfigure our TxFIFO sizes.
+  * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround
+  * @start_config_issued: true when StartConfig command has been issued
+  * @three_stage_setup: set if we perform a three phase setup
+@@ -855,9 +853,7 @@ struct dwc3 {
+       unsigned                has_lpm_erratum:1;
+       unsigned                is_utmi_l1_suspend:1;
+       unsigned                is_fpga:1;
+-      unsigned                needs_fifo_resize:1;
+       unsigned                pullups_connected:1;
+-      unsigned                resize_fifos:1;
+       unsigned                setup_packet_pending:1;
+       unsigned                three_stage_setup:1;
+       unsigned                usb3_lpm_capable:1;
+@@ -1025,7 +1021,6 @@ struct dwc3_gadget_ep_cmd_params {
+ /* prototypes */
+ void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
+-int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);
+ /* check whether we are on the DWC_usb31 core */
+ static inline bool dwc3_is_usb31(struct dwc3 *dwc)
+diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
+index eca2e6d..4454de0 100644
+--- a/drivers/usb/dwc3/ep0.c
++++ b/drivers/usb/dwc3/ep0.c
+@@ -586,9 +586,6 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
+                       reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+                       reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA);
+                       dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+-
+-                      dwc->resize_fifos = true;
+-                      dwc3_trace(trace_dwc3_ep0, "resize FIFOs flag SET");
+               }
+               break;
+@@ -1027,12 +1024,6 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep)
+ static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)
+ {
+-      if (dwc->resize_fifos) {
+-              dwc3_trace(trace_dwc3_ep0, "Resizing FIFOs");
+-              dwc3_gadget_resize_tx_fifos(dwc);
+-              dwc->resize_fifos = 0;
+-      }
+-
+       WARN_ON(dwc3_ep0_start_control_status(dep));
+ }
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index d54a028..3a5c271 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -145,92 +145,6 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
+       return -ETIMEDOUT;
+ }
+-/**
+- * dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for current use-case
+- * @dwc: pointer to our context structure
+- *
+- * This function will a best effort FIFO allocation in order
+- * to improve FIFO usage and throughput, while still allowing
+- * us to enable as many endpoints as possible.
+- *
+- * Keep in mind that this operation will be highly dependent
+- * on the configured size for RAM1 - which contains TxFifo -,
+- * the amount of endpoints enabled on coreConsultant tool, and
+- * the width of the Master Bus.
+- *
+- * In the ideal world, we would always be able to satisfy the
+- * following equation:
+- *
+- * ((512 + 2 * MDWIDTH-Bytes) + (Number of IN Endpoints - 1) * \
+- * (3 * (1024 + MDWIDTH-Bytes) + MDWIDTH-Bytes)) / MDWIDTH-Bytes
+- *
+- * Unfortunately, due to many variables that's not always the case.
+- */
+-int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc)
+-{
+-      int             last_fifo_depth = 0;
+-      int             ram1_depth;
+-      int             fifo_size;
+-      int             mdwidth;
+-      int             num;
+-
+-      if (!dwc->needs_fifo_resize)
+-              return 0;
+-
+-      ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
+-      mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
+-
+-      /* MDWIDTH is represented in bits, we need it in bytes */
+-      mdwidth >>= 3;
+-
+-      /*
+-       * FIXME For now we will only allocate 1 wMaxPacketSize space
+-       * for each enabled endpoint, later patches will come to
+-       * improve this algorithm so that we better use the internal
+-       * FIFO space
+-       */
+-      for (num = 0; num < dwc->num_in_eps; num++) {
+-              /* bit0 indicates direction; 1 means IN ep */
+-              struct dwc3_ep  *dep = dwc->eps[(num << 1) | 1];
+-              int             mult = 1;
+-              int             tmp;
+-
+-              if (!(dep->flags & DWC3_EP_ENABLED))
+-                      continue;
+-
+-              if (usb_endpoint_xfer_bulk(dep->endpoint.desc)
+-                              || usb_endpoint_xfer_isoc(dep->endpoint.desc))
+-                      mult = 3;
+-
+-              /*
+-               * REVISIT: the following assumes we will always have enough
+-               * space available on the FIFO RAM for all possible use cases.
+-               * Make sure that's true somehow and change FIFO allocation
+-               * accordingly.
+-               *
+-               * If we have Bulk or Isochronous endpoints, we want
+-               * them to be able to be very, very fast. So we're giving
+-               * those endpoints a fifo_size which is enough for 3 full
+-               * packets
+-               */
+-              tmp = mult * (dep->endpoint.maxpacket + mdwidth);
+-              tmp += mdwidth;
+-
+-              fifo_size = DIV_ROUND_UP(tmp, mdwidth);
+-
+-              fifo_size |= (last_fifo_depth << 16);
+-
+-              dwc3_trace(trace_dwc3_gadget, "%s: Fifo Addr %04x Size %d",
+-                              dep->name, last_fifo_depth, fifo_size & 0xffff);
+-
+-              dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num), fifo_size);
+-
+-              last_fifo_depth += (fifo_size & 0xffff);
+-      }
+-
+-      return 0;
+-}
+-
+ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
+               int status)
+ {
+diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
+index 2bb4d3a..aaa6f00 100644
+--- a/drivers/usb/dwc3/platform_data.h
++++ b/drivers/usb/dwc3/platform_data.h
+@@ -23,7 +23,6 @@
+ struct dwc3_platform_data {
+       enum usb_device_speed maximum_speed;
+       enum usb_dr_mode dr_mode;
+-      bool tx_fifo_resize;
+       bool usb3_lpm_capable;
+       unsigned is_utmi_l1_suspend:1;
+-- 
+cgit v0.12
diff --git a/target/linux/ipq806x/patches-4.4/096-08-usb-dwc3-remove-num_event_buffers.patch b/target/linux/ipq806x/patches-4.4/096-08-usb-dwc3-remove-num_event_buffers.patch
new file mode 100644 (file)
index 0000000..8bc0b98
--- /dev/null
@@ -0,0 +1,273 @@
+From 660e9bde74d6915227d7ee3485b11e5f52637b26 Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <felipe.balbi@linux.intel.com>
+Date: Wed, 30 Mar 2016 09:26:24 +0300
+Subject: usb: dwc3: remove num_event_buffers
+
+We never, ever route any of the other event buffers
+so we might as well drop support for them.
+
+Until someone has a real, proper benefit for
+multiple event buffers, we will rely on a single
+one. This also helps reduce memory footprint of
+dwc3.ko which won't allocate memory for the extra
+event buffers.
+
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/dwc3/core.c   | 81 +++++++++++++++++++----------------------------
+ drivers/usb/dwc3/core.h   |  2 --
+ drivers/usb/dwc3/gadget.c | 38 +++++++---------------
+ 3 files changed, 44 insertions(+), 77 deletions(-)
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 67d183a..9e5c57c7 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -203,13 +203,10 @@ static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
+ static void dwc3_free_event_buffers(struct dwc3 *dwc)
+ {
+       struct dwc3_event_buffer        *evt;
+-      int i;
+-      for (i = 0; i < dwc->num_event_buffers; i++) {
+-              evt = dwc->ev_buffs[i];
+-              if (evt)
+-                      dwc3_free_one_event_buffer(dwc, evt);
+-      }
++      evt = dwc->ev_buffs[0];
++      if (evt)
++              dwc3_free_one_event_buffer(dwc, evt);
+ }
+ /**
+@@ -222,27 +219,19 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
+  */
+ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
+ {
+-      int                     num;
+-      int                     i;
+-
+-      num = DWC3_NUM_INT(dwc->hwparams.hwparams1);
+-      dwc->num_event_buffers = num;
++      struct dwc3_event_buffer *evt;
+-      dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num,
++      dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs),
+                       GFP_KERNEL);
+       if (!dwc->ev_buffs)
+               return -ENOMEM;
+-      for (i = 0; i < num; i++) {
+-              struct dwc3_event_buffer        *evt;
+-
+-              evt = dwc3_alloc_one_event_buffer(dwc, length);
+-              if (IS_ERR(evt)) {
+-                      dev_err(dwc->dev, "can't allocate event buffer\n");
+-                      return PTR_ERR(evt);
+-              }
+-              dwc->ev_buffs[i] = evt;
++      evt = dwc3_alloc_one_event_buffer(dwc, length);
++      if (IS_ERR(evt)) {
++              dev_err(dwc->dev, "can't allocate event buffer\n");
++              return PTR_ERR(evt);
+       }
++      dwc->ev_buffs[0] = evt;
+       return 0;
+ }
+@@ -256,25 +245,22 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
+ static int dwc3_event_buffers_setup(struct dwc3 *dwc)
+ {
+       struct dwc3_event_buffer        *evt;
+-      int                             n;
+-      for (n = 0; n < dwc->num_event_buffers; n++) {
+-              evt = dwc->ev_buffs[n];
+-              dwc3_trace(trace_dwc3_core,
+-                              "Event buf %p dma %08llx length %d\n",
+-                              evt->buf, (unsigned long long) evt->dma,
+-                              evt->length);
+-
+-              evt->lpos = 0;
+-
+-              dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n),
+-                              lower_32_bits(evt->dma));
+-              dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n),
+-                              upper_32_bits(evt->dma));
+-              dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n),
+-                              DWC3_GEVNTSIZ_SIZE(evt->length));
+-              dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
+-      }
++      evt = dwc->ev_buffs[0];
++      dwc3_trace(trace_dwc3_core,
++                      "Event buf %p dma %08llx length %d\n",
++                      evt->buf, (unsigned long long) evt->dma,
++                      evt->length);
++
++      evt->lpos = 0;
++
++      dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0),
++                      lower_32_bits(evt->dma));
++      dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0),
++                      upper_32_bits(evt->dma));
++      dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
++                      DWC3_GEVNTSIZ_SIZE(evt->length));
++      dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
+       return 0;
+ }
+@@ -282,19 +268,16 @@ static int dwc3_event_buffers_setup(struct dwc3 *dwc)
+ static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
+ {
+       struct dwc3_event_buffer        *evt;
+-      int                             n;
+-      for (n = 0; n < dwc->num_event_buffers; n++) {
+-              evt = dwc->ev_buffs[n];
++      evt = dwc->ev_buffs[0];
+-              evt->lpos = 0;
++      evt->lpos = 0;
+-              dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0);
+-              dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0);
+-              dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), DWC3_GEVNTSIZ_INTMASK
+-                              | DWC3_GEVNTSIZ_SIZE(0));
+-              dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
+-      }
++      dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), 0);
++      dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0);
++      dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
++                      | DWC3_GEVNTSIZ_SIZE(0));
++      dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
+ }
+ static int dwc3_alloc_scratch_buffers(struct dwc3 *dwc)
+diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
+index 4ea4b51..be03999 100644
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -667,7 +667,6 @@ struct dwc3_scratchpad_array {
+  * @regs: base address for our registers
+  * @regs_size: address space size
+  * @nr_scratch: number of scratch buffers
+- * @num_event_buffers: calculated number of event buffers
+  * @u1u2: only used on revisions <1.83a for workaround
+  * @maximum_speed: maximum speed requested (mainly for testing purposes)
+  * @revision: revision register contents
+@@ -778,7 +777,6 @@ struct dwc3 {
+       u32                     gctl;
+       u32                     nr_scratch;
+-      u32                     num_event_buffers;
+       u32                     u1u2;
+       u32                     maximum_speed;
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index e6bd3a9..5e6a495 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2602,14 +2602,14 @@ static void dwc3_process_event_entry(struct dwc3 *dwc,
+       }
+ }
+-static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf)
++static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc)
+ {
+       struct dwc3_event_buffer *evt;
+       irqreturn_t ret = IRQ_NONE;
+       int left;
+       u32 reg;
+-      evt = dwc->ev_buffs[buf];
++      evt = dwc->ev_buffs[0];
+       left = evt->count;
+       if (!(evt->flags & DWC3_EVENT_PENDING))
+@@ -2634,7 +2634,7 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf)
+               evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE;
+               left -= 4;
+-              dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(buf), 4);
++              dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 4);
+       }
+       evt->count = 0;
+@@ -2642,9 +2642,9 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf)
+       ret = IRQ_HANDLED;
+       /* Unmask interrupt */
+-      reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(buf));
++      reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(0));
+       reg &= ~DWC3_GEVNTSIZ_INTMASK;
+-      dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(buf), reg);
++      dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), reg);
+       return ret;
+ }
+@@ -2654,27 +2654,23 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc)
+       struct dwc3 *dwc = _dwc;
+       unsigned long flags;
+       irqreturn_t ret = IRQ_NONE;
+-      int i;
+       spin_lock_irqsave(&dwc->lock, flags);
+-
+-      for (i = 0; i < dwc->num_event_buffers; i++)
+-              ret |= dwc3_process_event_buf(dwc, i);
+-
++      ret = dwc3_process_event_buf(dwc);
+       spin_unlock_irqrestore(&dwc->lock, flags);
+       return ret;
+ }
+-static irqreturn_t dwc3_check_event_buf(struct dwc3 *dwc, u32 buf)
++static irqreturn_t dwc3_check_event_buf(struct dwc3 *dwc)
+ {
+       struct dwc3_event_buffer *evt;
+       u32 count;
+       u32 reg;
+-      evt = dwc->ev_buffs[buf];
++      evt = dwc->ev_buffs[0];
+-      count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(buf));
++      count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
+       count &= DWC3_GEVNTCOUNT_MASK;
+       if (!count)
+               return IRQ_NONE;
+@@ -2683,9 +2679,9 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3 *dwc, u32 buf)
+       evt->flags |= DWC3_EVENT_PENDING;
+       /* Mask interrupt */
+-      reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(buf));
++      reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(0));
+       reg |= DWC3_GEVNTSIZ_INTMASK;
+-      dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(buf), reg);
++      dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), reg);
+       return IRQ_WAKE_THREAD;
+ }
+@@ -2693,18 +2689,8 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3 *dwc, u32 buf)
+ static irqreturn_t dwc3_interrupt(int irq, void *_dwc)
+ {
+       struct dwc3                     *dwc = _dwc;
+-      int                             i;
+-      irqreturn_t                     ret = IRQ_NONE;
+-
+-      for (i = 0; i < dwc->num_event_buffers; i++) {
+-              irqreturn_t status;
+-              status = dwc3_check_event_buf(dwc, i);
+-              if (status == IRQ_WAKE_THREAD)
+-                      ret = status;
+-      }
+-
+-      return ret;
++      return dwc3_check_event_buf(dwc);
+ }
+ /**
+-- 
+cgit v0.12
diff --git a/target/linux/ipq806x/patches-4.4/096-09-usb-dwc3-drop-ev_buffs-array.patch b/target/linux/ipq806x/patches-4.4/096-09-usb-dwc3-drop-ev_buffs-array.patch
new file mode 100644 (file)
index 0000000..64d796c
--- /dev/null
@@ -0,0 +1,104 @@
+From 696c8b1282205caa5206264449f80ef756f14ef7 Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <felipe.balbi@linux.intel.com>
+Date: Wed, 30 Mar 2016 09:37:03 +0300
+Subject: usb: dwc3: drop ev_buffs array
+
+we will be using a single event buffer and that
+renders ev_buffs array unnecessary. Let's remove it
+in favor of a single pointer to a single event
+buffer.
+
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/dwc3/core.c   | 13 ++++---------
+ drivers/usb/dwc3/core.h   |  2 +-
+ drivers/usb/dwc3/gadget.c |  4 ++--
+ 3 files changed, 7 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 9e5c57c7..05b7ec3 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -204,7 +204,7 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
+ {
+       struct dwc3_event_buffer        *evt;
+-      evt = dwc->ev_buffs[0];
++      evt = dwc->ev_buf;
+       if (evt)
+               dwc3_free_one_event_buffer(dwc, evt);
+ }
+@@ -221,17 +221,12 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
+ {
+       struct dwc3_event_buffer *evt;
+-      dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs),
+-                      GFP_KERNEL);
+-      if (!dwc->ev_buffs)
+-              return -ENOMEM;
+-
+       evt = dwc3_alloc_one_event_buffer(dwc, length);
+       if (IS_ERR(evt)) {
+               dev_err(dwc->dev, "can't allocate event buffer\n");
+               return PTR_ERR(evt);
+       }
+-      dwc->ev_buffs[0] = evt;
++      dwc->ev_buf = evt;
+       return 0;
+ }
+@@ -246,7 +241,7 @@ static int dwc3_event_buffers_setup(struct dwc3 *dwc)
+ {
+       struct dwc3_event_buffer        *evt;
+-      evt = dwc->ev_buffs[0];
++      evt = dwc->ev_buf;
+       dwc3_trace(trace_dwc3_core,
+                       "Event buf %p dma %08llx length %d\n",
+                       evt->buf, (unsigned long long) evt->dma,
+@@ -269,7 +264,7 @@ static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
+ {
+       struct dwc3_event_buffer        *evt;
+-      evt = dwc->ev_buffs[0];
++      evt = dwc->ev_buf;
+       evt->lpos = 0;
+diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
+index be03999..df72234a 100644
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -753,7 +753,7 @@ struct dwc3 {
+       struct platform_device  *xhci;
+       struct resource         xhci_resources[DWC3_XHCI_RESOURCES_NUM];
+-      struct dwc3_event_buffer **ev_buffs;
++      struct dwc3_event_buffer *ev_buf;
+       struct dwc3_ep          *eps[DWC3_ENDPOINTS_NUM];
+       struct usb_gadget       gadget;
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 5e6a495..96dfde0 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2609,7 +2609,7 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc)
+       int left;
+       u32 reg;
+-      evt = dwc->ev_buffs[0];
++      evt = dwc->ev_buf;
+       left = evt->count;
+       if (!(evt->flags & DWC3_EVENT_PENDING))
+@@ -2668,7 +2668,7 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3 *dwc)
+       u32 count;
+       u32 reg;
+-      evt = dwc->ev_buffs[0];
++      evt = dwc->ev_buf;
+       count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
+       count &= DWC3_GEVNTCOUNT_MASK;
+-- 
+cgit v0.12
diff --git a/target/linux/ipq806x/patches-4.4/096-10-usb-dwc3-core-fix-PHY-handling-during-suspend.patch b/target/linux/ipq806x/patches-4.4/096-10-usb-dwc3-core-fix-PHY-handling-during-suspend.patch
new file mode 100644 (file)
index 0000000..87f1562
--- /dev/null
@@ -0,0 +1,71 @@
+From 5c4ad318de3b8e8680d654c82a254c4b65243739 Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <balbi@kernel.org>
+Date: Mon, 11 Apr 2016 17:12:34 +0300
+Subject: usb: dwc3: core: fix PHY handling during suspend
+
+we need to power off the PHY during suspend and
+power it back on during resume.
+
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+[nsekhar@ti.com: fix call to usb_phy_set_suspend() in dwc3_suspend()]
+Signed-off-by: Sekhar Nori <nsekhar@ti.com>
+Signed-off-by: Roger Quadros <rogerq@ti.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/dwc3/core.c | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index fa20f5a9..34277ce 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -1150,6 +1150,11 @@ static int dwc3_suspend(struct device *dev)
+       phy_exit(dwc->usb2_generic_phy);
+       phy_exit(dwc->usb3_generic_phy);
++      usb_phy_set_suspend(dwc->usb2_phy, 1);
++      usb_phy_set_suspend(dwc->usb3_phy, 1);
++      WARN_ON(phy_power_off(dwc->usb2_generic_phy) < 0);
++      WARN_ON(phy_power_off(dwc->usb3_generic_phy) < 0);
++
+       pinctrl_pm_select_sleep_state(dev);
+       return 0;
+@@ -1163,11 +1168,21 @@ static int dwc3_resume(struct device *dev)
+       pinctrl_pm_select_default_state(dev);
++      usb_phy_set_suspend(dwc->usb2_phy, 0);
++      usb_phy_set_suspend(dwc->usb3_phy, 0);
++      ret = phy_power_on(dwc->usb2_generic_phy);
++      if (ret < 0)
++              return ret;
++
++      ret = phy_power_on(dwc->usb3_generic_phy);
++      if (ret < 0)
++              goto err_usb2phy_power;
++
+       usb_phy_init(dwc->usb3_phy);
+       usb_phy_init(dwc->usb2_phy);
+       ret = phy_init(dwc->usb2_generic_phy);
+       if (ret < 0)
+-              return ret;
++              goto err_usb3phy_power;
+       ret = phy_init(dwc->usb3_generic_phy);
+       if (ret < 0)
+@@ -1200,6 +1215,12 @@ static int dwc3_resume(struct device *dev)
+ err_usb2phy_init:
+       phy_exit(dwc->usb2_generic_phy);
++err_usb3phy_power:
++      phy_power_off(dwc->usb3_generic_phy);
++
++err_usb2phy_power:
++      phy_power_off(dwc->usb2_generic_phy);
++
+       return ret;
+ }
+-- 
+cgit v0.12
diff --git a/target/linux/ipq806x/patches-4.4/097-1-usb-dwc3-add-generic-OF-glue-layer.patch b/target/linux/ipq806x/patches-4.4/097-1-usb-dwc3-add-generic-OF-glue-layer.patch
new file mode 100644 (file)
index 0000000..214bedc
--- /dev/null
@@ -0,0 +1,234 @@
+From 41c2b5280cd2fa3e198c422cdf223ba6e48f857a Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <balbi@ti.com>
+Date: Wed, 18 Nov 2015 13:15:20 -0600
+Subject: [PATCH] usb: dwc3: add generic OF glue layer
+
+For simple platforms which merely enable some clocks
+and populate its children, we can use this generic
+glue layer to avoid boilerplate code duplication.
+
+For now this supports Qcom and Xilinx, but if we
+find a way to add generic handling of regulators and
+optional PHYs, we can absorb exynos as well.
+
+Tested-by: Subbaraya Sundeep Bhatta <subbaraya.sundeep.bhatta@xilinx.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+(cherry picked from commit 16adc674d0d68a50dfc725574738d7ae11cf5d7e)
+
+Change-Id: I6fd260442997b198dc12ca726814b7a9518e6353
+Signed-off-by: Nitheesh Sekar <nsekar@codeaurora.org>
+---
+ drivers/usb/dwc3/Kconfig          |   9 ++
+ drivers/usb/dwc3/Makefile         |   1 +
+ drivers/usb/dwc3/dwc3-of-simple.c | 178 ++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 188 insertions(+)
+ create mode 100644 drivers/usb/dwc3/dwc3-of-simple.c
+
+--- a/drivers/usb/dwc3/Kconfig
++++ b/drivers/usb/dwc3/Kconfig
+@@ -87,6 +87,15 @@ config USB_DWC3_KEYSTONE
+         Support of USB2/3 functionality in TI Keystone2 platforms.
+         Say 'Y' or 'M' here if you have one such device
++config USB_DWC3_OF_SIMPLE
++       tristate "Generic OF Simple Glue Layer"
++       depends on OF && COMMON_CLK
++       default USB_DWC3
++       help
++         Support USB2/3 functionality in simple SoC integrations.
++       Currently supports Xilinx and Qualcomm DWC USB3 IP.
++       Say 'Y' or 'M' if you have one such device.
++
+ config USB_DWC3_ST
+       tristate "STMicroelectronics Platforms"
+       depends on ARCH_STI && OF
+--- a/drivers/usb/dwc3/Makefile
++++ b/drivers/usb/dwc3/Makefile
+@@ -37,5 +37,6 @@ obj-$(CONFIG_USB_DWC3_OMAP)          += dwc3-oma
+ obj-$(CONFIG_USB_DWC3_EXYNOS)         += dwc3-exynos.o
+ obj-$(CONFIG_USB_DWC3_PCI)            += dwc3-pci.o
+ obj-$(CONFIG_USB_DWC3_KEYSTONE)               += dwc3-keystone.o
++obj-$(CONFIG_USB_DWC3_OF_SIMPLE)      += dwc3-of-simple.o
+ obj-$(CONFIG_USB_DWC3_QCOM)           += dwc3-qcom.o
+ obj-$(CONFIG_USB_DWC3_ST)             += dwc3-st.o
+--- /dev/null
++++ b/drivers/usb/dwc3/dwc3-of-simple.c
+@@ -0,0 +1,178 @@
++/**
++ * dwc3-of-simple.c - OF glue layer for simple integrations
++ *
++ * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
++ *
++ * Author: Felipe Balbi <balbi@ti.com>
++ *
++ * This program is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2  of
++ * the License as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * This is a combination of the old dwc3-qcom.c by Ivan T. Ivanov
++ * <iivanov@mm-sol.com> and the original patch adding support for Xilinx' SoC
++ * by Subbaraya Sundeep Bhatta <subbaraya.sundeep.bhatta@xilinx.com>
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/of.h>
++#include <linux/of_platform.h>
++#include <linux/pm_runtime.h>
++
++struct dwc3_of_simple {
++      struct device           *dev;
++      struct clk              **clks;
++      int                     num_clocks;
++};
++
++static int dwc3_of_simple_probe(struct platform_device *pdev)
++{
++      struct dwc3_of_simple   *simple;
++      struct device           *dev = &pdev->dev;
++      struct device_node      *np = dev->of_node;
++
++      int                     ret;
++      int                     i;
++
++      simple = devm_kzalloc(dev, sizeof(*simple), GFP_KERNEL);
++      if (!simple)
++              return -ENOMEM;
++
++      ret = of_clk_get_parent_count(np);
++      if (ret < 0)
++              return ret;
++
++      simple->num_clocks = ret;
++
++      simple->clks = devm_kcalloc(dev, simple->num_clocks,
++                      sizeof(struct clk *), GFP_KERNEL);
++      if (!simple->clks)
++              return -ENOMEM;
++
++      simple->dev = dev;
++
++      for (i = 0; i < simple->num_clocks; i++) {
++              struct clk      *clk;
++
++              clk = of_clk_get(np, i);
++              if (IS_ERR(clk)) {
++                      while (--i >= 0)
++                              clk_put(simple->clks[i]);
++                      return PTR_ERR(clk);
++              }
++
++              ret = clk_prepare_enable(clk);
++              if (ret < 0) {
++                      while (--i >= 0) {
++                              clk_disable_unprepare(simple->clks[i]);
++                              clk_put(simple->clks[i]);
++                      }
++                      clk_put(clk);
++
++                      return ret;
++              }
++
++              simple->clks[i] = clk;
++      }
++
++      ret = of_platform_populate(np, NULL, NULL, dev);
++      if (ret) {
++              for (i = 0; i < simple->num_clocks; i++) {
++                      clk_disable_unprepare(simple->clks[i]);
++                      clk_put(simple->clks[i]);
++              }
++
++              return ret;
++      }
++
++      pm_runtime_set_active(dev);
++      pm_runtime_enable(dev);
++      pm_runtime_get_sync(dev);
++
++      return 0;
++}
++
++static int dwc3_of_simple_remove(struct platform_device *pdev)
++{
++      struct dwc3_of_simple   *simple = platform_get_drvdata(pdev);
++      struct device           *dev = &pdev->dev;
++      int                     i;
++
++      for (i = 0; i < simple->num_clocks; i++) {
++              clk_unprepare(simple->clks[i]);
++              clk_put(simple->clks[i]);
++      }
++
++      of_platform_depopulate(dev);
++
++      pm_runtime_put_sync(dev);
++      pm_runtime_disable(dev);
++
++      return 0;
++}
++
++static int dwc3_of_simple_runtime_suspend(struct device *dev)
++{
++      struct dwc3_of_simple   *simple = dev_get_drvdata(dev);
++      int                     i;
++
++      for (i = 0; i < simple->num_clocks; i++)
++              clk_disable(simple->clks[i]);
++
++      return 0;
++}
++
++static int dwc3_of_simple_runtime_resume(struct device *dev)
++{
++      struct dwc3_of_simple   *simple = dev_get_drvdata(dev);
++      int                     ret;
++      int                     i;
++
++      for (i = 0; i < simple->num_clocks; i++) {
++              ret = clk_enable(simple->clks[i]);
++              if (ret < 0) {
++                      while (--i >= 0)
++                              clk_disable(simple->clks[i]);
++                      return ret;
++              }
++      }
++
++      return 0;
++}
++
++static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = {
++      SET_RUNTIME_PM_OPS(dwc3_of_simple_runtime_suspend,
++                      dwc3_of_simple_runtime_resume, NULL)
++};
++
++static const struct of_device_id of_dwc3_simple_match[] = {
++      { .compatible = "qcom,dwc3" },
++      { .compatible = "xlnx,zynqmp-dwc3" },
++      { /* Sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, of_dwc3_simple_match);
++
++static struct platform_driver dwc3_of_simple_driver = {
++      .probe          = dwc3_of_simple_probe,
++      .remove         = dwc3_of_simple_remove,
++      .driver         = {
++              .name   = "dwc3-of-simple",
++              .of_match_table = of_dwc3_simple_match,
++      },
++};
++
++module_platform_driver(dwc3_of_simple_driver);
++MODULE_LICENSE("GPL v2");
++MODULE_DESCRIPTION("DesignWare USB3 OF Simple Glue Layer");
++MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
diff --git a/target/linux/ipq806x/patches-4.4/097-2-usb-dwc3-of-simple-fix-build-warning-on-PM.patch b/target/linux/ipq806x/patches-4.4/097-2-usb-dwc3-of-simple-fix-build-warning-on-PM.patch
new file mode 100644 (file)
index 0000000..b982c82
--- /dev/null
@@ -0,0 +1,36 @@
+From 131386d63ca3177d471aa93808c69b85fdac520d Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <balbi@ti.com>
+Date: Tue, 22 Dec 2015 21:56:10 -0600
+Subject: [PATCH] usb: dwc3: of-simple: fix build warning on !PM
+
+if we have a !PM kernel build, our runtime
+suspend/resume callbacks will be left defined but
+unused. Add a ifdef CONFIG_PM guard.
+
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+(cherry picked from commit 5072cfc40a80cea3749fd3413b3896630d8c787e)
+
+Change-Id: I088186c33aa917ec8da2985372ceefc289b24242
+Signed-off-by: Nitheesh Sekar <nsekar@codeaurora.org>
+---
+ drivers/usb/dwc3/dwc3-of-simple.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/dwc3/dwc3-of-simple.c
++++ b/drivers/usb/dwc3/dwc3-of-simple.c
+@@ -122,6 +122,7 @@ static int dwc3_of_simple_remove(struct
+       return 0;
+ }
++#ifdef CONFIG_PM
+ static int dwc3_of_simple_runtime_suspend(struct device *dev)
+ {
+       struct dwc3_of_simple   *simple = dev_get_drvdata(dev);
+@@ -150,6 +151,7 @@ static int dwc3_of_simple_runtime_resume
+       return 0;
+ }
++#endif
+ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = {
+       SET_RUNTIME_PM_OPS(dwc3_of_simple_runtime_suspend,
diff --git a/target/linux/ipq806x/patches-4.4/097-3-usb-dwc3-Remove-impossible-check-for-of_clk_get_pare.patch b/target/linux/ipq806x/patches-4.4/097-3-usb-dwc3-Remove-impossible-check-for-of_clk_get_pare.patch
new file mode 100644 (file)
index 0000000..32f9e34
--- /dev/null
@@ -0,0 +1,47 @@
+From 07c8b15688055d81ac8e1c8c964b9e4c302287f1 Mon Sep 17 00:00:00 2001
+From: Stephen Boyd <sboyd@codeaurora.org>
+Date: Mon, 22 Feb 2016 11:12:47 -0800
+Subject: [PATCH] usb: dwc3: Remove impossible check for
+ of_clk_get_parent_count() < 0
+
+The check for < 0 is impossible now that
+of_clk_get_parent_count() returns an unsigned int. Simplify the
+code and update the types.
+
+Acked-by: Felipe Balbi <balbi@kernel.org>
+Cc: <linux-usb@vger.kernel.org>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+(cherry picked from commit 3d755dcc20dd452b52532eca17da40ebbd12aee9)
+
+Change-Id: Iaa38e064d801fb36c855fea51c0443840368e0d3
+Signed-off-by: Nitheesh Sekar <nsekar@codeaurora.org>
+---
+ drivers/usb/dwc3/dwc3-of-simple.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/dwc3/dwc3-of-simple.c
++++ b/drivers/usb/dwc3/dwc3-of-simple.c
+@@ -42,6 +42,7 @@ static int dwc3_of_simple_probe(struct p
+       struct device           *dev = &pdev->dev;
+       struct device_node      *np = dev->of_node;
++      unsigned int            count;
+       int                     ret;
+       int                     i;
+@@ -49,11 +50,11 @@ static int dwc3_of_simple_probe(struct p
+       if (!simple)
+               return -ENOMEM;
+-      ret = of_clk_get_parent_count(np);
+-      if (ret < 0)
+-              return ret;
++      count = of_clk_get_parent_count(np);
++      if (!count)
++              return -ENOENT;
+-      simple->num_clocks = ret;
++      simple->num_clocks = count;
+       simple->clks = devm_kcalloc(dev, simple->num_clocks,
+                       sizeof(struct clk *), GFP_KERNEL);
diff --git a/target/linux/ipq806x/patches-4.4/097-4-usb-dwc3-fix-missing-platform_set_drvdata-in-dwc3_of_simple_probe.patch b/target/linux/ipq806x/patches-4.4/097-4-usb-dwc3-fix-missing-platform_set_drvdata-in-dwc3_of_simple_probe.patch
new file mode 100644 (file)
index 0000000..2aeadc3
--- /dev/null
@@ -0,0 +1,31 @@
+From 4c4f106c032ff32b89c98a4d819e68e6e643c14e Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <weiyj.lk@gmail.com>
+Date: Tue, 26 Jul 2016 14:47:00 +0000
+Subject: usb: dwc3: fix missing platform_set_drvdata() in
+ dwc3_of_simple_probe()
+
+Add missing platform_set_drvdata() in dwc3_of_simple_probe(), otherwise
+calling platform_get_drvdata() in remove returns NULL.
+
+This is detected by Coccinelle semantic patch.
+
+Signed-off-by: Wei Yongjun <weiyj.lk@gmail.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/dwc3/dwc3-of-simple.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c
+index 9743353..e56d59b 100644
+--- a/drivers/usb/dwc3/dwc3-of-simple.c
++++ b/drivers/usb/dwc3/dwc3-of-simple.c
+@@ -61,6 +61,7 @@ static int dwc3_of_simple_probe(struct platform_device *pdev)
+       if (!simple->clks)
+               return -ENOMEM;
++      platform_set_drvdata(pdev, simple);
+       simple->dev = dev;
+       for (i = 0; i < simple->num_clocks; i++) {
+-- 
+cgit v0.12
diff --git a/target/linux/ipq806x/patches-4.4/097-usb-dwc3-add-generic-OF-glue-layer.patch b/target/linux/ipq806x/patches-4.4/097-usb-dwc3-add-generic-OF-glue-layer.patch
deleted file mode 100644 (file)
index 214bedc..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-From 41c2b5280cd2fa3e198c422cdf223ba6e48f857a Mon Sep 17 00:00:00 2001
-From: Felipe Balbi <balbi@ti.com>
-Date: Wed, 18 Nov 2015 13:15:20 -0600
-Subject: [PATCH] usb: dwc3: add generic OF glue layer
-
-For simple platforms which merely enable some clocks
-and populate its children, we can use this generic
-glue layer to avoid boilerplate code duplication.
-
-For now this supports Qcom and Xilinx, but if we
-find a way to add generic handling of regulators and
-optional PHYs, we can absorb exynos as well.
-
-Tested-by: Subbaraya Sundeep Bhatta <subbaraya.sundeep.bhatta@xilinx.com>
-Signed-off-by: Felipe Balbi <balbi@ti.com>
-(cherry picked from commit 16adc674d0d68a50dfc725574738d7ae11cf5d7e)
-
-Change-Id: I6fd260442997b198dc12ca726814b7a9518e6353
-Signed-off-by: Nitheesh Sekar <nsekar@codeaurora.org>
----
- drivers/usb/dwc3/Kconfig          |   9 ++
- drivers/usb/dwc3/Makefile         |   1 +
- drivers/usb/dwc3/dwc3-of-simple.c | 178 ++++++++++++++++++++++++++++++++++++++
- 3 files changed, 188 insertions(+)
- create mode 100644 drivers/usb/dwc3/dwc3-of-simple.c
-
---- a/drivers/usb/dwc3/Kconfig
-+++ b/drivers/usb/dwc3/Kconfig
-@@ -87,6 +87,15 @@ config USB_DWC3_KEYSTONE
-         Support of USB2/3 functionality in TI Keystone2 platforms.
-         Say 'Y' or 'M' here if you have one such device
-+config USB_DWC3_OF_SIMPLE
-+       tristate "Generic OF Simple Glue Layer"
-+       depends on OF && COMMON_CLK
-+       default USB_DWC3
-+       help
-+         Support USB2/3 functionality in simple SoC integrations.
-+       Currently supports Xilinx and Qualcomm DWC USB3 IP.
-+       Say 'Y' or 'M' if you have one such device.
-+
- config USB_DWC3_ST
-       tristate "STMicroelectronics Platforms"
-       depends on ARCH_STI && OF
---- a/drivers/usb/dwc3/Makefile
-+++ b/drivers/usb/dwc3/Makefile
-@@ -37,5 +37,6 @@ obj-$(CONFIG_USB_DWC3_OMAP)          += dwc3-oma
- obj-$(CONFIG_USB_DWC3_EXYNOS)         += dwc3-exynos.o
- obj-$(CONFIG_USB_DWC3_PCI)            += dwc3-pci.o
- obj-$(CONFIG_USB_DWC3_KEYSTONE)               += dwc3-keystone.o
-+obj-$(CONFIG_USB_DWC3_OF_SIMPLE)      += dwc3-of-simple.o
- obj-$(CONFIG_USB_DWC3_QCOM)           += dwc3-qcom.o
- obj-$(CONFIG_USB_DWC3_ST)             += dwc3-st.o
---- /dev/null
-+++ b/drivers/usb/dwc3/dwc3-of-simple.c
-@@ -0,0 +1,178 @@
-+/**
-+ * dwc3-of-simple.c - OF glue layer for simple integrations
-+ *
-+ * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
-+ *
-+ * Author: Felipe Balbi <balbi@ti.com>
-+ *
-+ * This program is free software: you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2  of
-+ * the License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * This is a combination of the old dwc3-qcom.c by Ivan T. Ivanov
-+ * <iivanov@mm-sol.com> and the original patch adding support for Xilinx' SoC
-+ * by Subbaraya Sundeep Bhatta <subbaraya.sundeep.bhatta@xilinx.com>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/platform_device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/pm_runtime.h>
-+
-+struct dwc3_of_simple {
-+      struct device           *dev;
-+      struct clk              **clks;
-+      int                     num_clocks;
-+};
-+
-+static int dwc3_of_simple_probe(struct platform_device *pdev)
-+{
-+      struct dwc3_of_simple   *simple;
-+      struct device           *dev = &pdev->dev;
-+      struct device_node      *np = dev->of_node;
-+
-+      int                     ret;
-+      int                     i;
-+
-+      simple = devm_kzalloc(dev, sizeof(*simple), GFP_KERNEL);
-+      if (!simple)
-+              return -ENOMEM;
-+
-+      ret = of_clk_get_parent_count(np);
-+      if (ret < 0)
-+              return ret;
-+
-+      simple->num_clocks = ret;
-+
-+      simple->clks = devm_kcalloc(dev, simple->num_clocks,
-+                      sizeof(struct clk *), GFP_KERNEL);
-+      if (!simple->clks)
-+              return -ENOMEM;
-+
-+      simple->dev = dev;
-+
-+      for (i = 0; i < simple->num_clocks; i++) {
-+              struct clk      *clk;
-+
-+              clk = of_clk_get(np, i);
-+              if (IS_ERR(clk)) {
-+                      while (--i >= 0)
-+                              clk_put(simple->clks[i]);
-+                      return PTR_ERR(clk);
-+              }
-+
-+              ret = clk_prepare_enable(clk);
-+              if (ret < 0) {
-+                      while (--i >= 0) {
-+                              clk_disable_unprepare(simple->clks[i]);
-+                              clk_put(simple->clks[i]);
-+                      }
-+                      clk_put(clk);
-+
-+                      return ret;
-+              }
-+
-+              simple->clks[i] = clk;
-+      }
-+
-+      ret = of_platform_populate(np, NULL, NULL, dev);
-+      if (ret) {
-+              for (i = 0; i < simple->num_clocks; i++) {
-+                      clk_disable_unprepare(simple->clks[i]);
-+                      clk_put(simple->clks[i]);
-+              }
-+
-+              return ret;
-+      }
-+
-+      pm_runtime_set_active(dev);
-+      pm_runtime_enable(dev);
-+      pm_runtime_get_sync(dev);
-+
-+      return 0;
-+}
-+
-+static int dwc3_of_simple_remove(struct platform_device *pdev)
-+{
-+      struct dwc3_of_simple   *simple = platform_get_drvdata(pdev);
-+      struct device           *dev = &pdev->dev;
-+      int                     i;
-+
-+      for (i = 0; i < simple->num_clocks; i++) {
-+              clk_unprepare(simple->clks[i]);
-+              clk_put(simple->clks[i]);
-+      }
-+
-+      of_platform_depopulate(dev);
-+
-+      pm_runtime_put_sync(dev);
-+      pm_runtime_disable(dev);
-+
-+      return 0;
-+}
-+
-+static int dwc3_of_simple_runtime_suspend(struct device *dev)
-+{
-+      struct dwc3_of_simple   *simple = dev_get_drvdata(dev);
-+      int                     i;
-+
-+      for (i = 0; i < simple->num_clocks; i++)
-+              clk_disable(simple->clks[i]);
-+
-+      return 0;
-+}
-+
-+static int dwc3_of_simple_runtime_resume(struct device *dev)
-+{
-+      struct dwc3_of_simple   *simple = dev_get_drvdata(dev);
-+      int                     ret;
-+      int                     i;
-+
-+      for (i = 0; i < simple->num_clocks; i++) {
-+              ret = clk_enable(simple->clks[i]);
-+              if (ret < 0) {
-+                      while (--i >= 0)
-+                              clk_disable(simple->clks[i]);
-+                      return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = {
-+      SET_RUNTIME_PM_OPS(dwc3_of_simple_runtime_suspend,
-+                      dwc3_of_simple_runtime_resume, NULL)
-+};
-+
-+static const struct of_device_id of_dwc3_simple_match[] = {
-+      { .compatible = "qcom,dwc3" },
-+      { .compatible = "xlnx,zynqmp-dwc3" },
-+      { /* Sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, of_dwc3_simple_match);
-+
-+static struct platform_driver dwc3_of_simple_driver = {
-+      .probe          = dwc3_of_simple_probe,
-+      .remove         = dwc3_of_simple_remove,
-+      .driver         = {
-+              .name   = "dwc3-of-simple",
-+              .of_match_table = of_dwc3_simple_match,
-+      },
-+};
-+
-+module_platform_driver(dwc3_of_simple_driver);
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("DesignWare USB3 OF Simple Glue Layer");
-+MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
diff --git a/target/linux/ipq806x/patches-4.4/098-usb-dwc3-of-simple-fix-build-warning-on-PM.patch b/target/linux/ipq806x/patches-4.4/098-usb-dwc3-of-simple-fix-build-warning-on-PM.patch
deleted file mode 100644 (file)
index b982c82..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-From 131386d63ca3177d471aa93808c69b85fdac520d Mon Sep 17 00:00:00 2001
-From: Felipe Balbi <balbi@ti.com>
-Date: Tue, 22 Dec 2015 21:56:10 -0600
-Subject: [PATCH] usb: dwc3: of-simple: fix build warning on !PM
-
-if we have a !PM kernel build, our runtime
-suspend/resume callbacks will be left defined but
-unused. Add a ifdef CONFIG_PM guard.
-
-Signed-off-by: Felipe Balbi <balbi@ti.com>
-(cherry picked from commit 5072cfc40a80cea3749fd3413b3896630d8c787e)
-
-Change-Id: I088186c33aa917ec8da2985372ceefc289b24242
-Signed-off-by: Nitheesh Sekar <nsekar@codeaurora.org>
----
- drivers/usb/dwc3/dwc3-of-simple.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/usb/dwc3/dwc3-of-simple.c
-+++ b/drivers/usb/dwc3/dwc3-of-simple.c
-@@ -122,6 +122,7 @@ static int dwc3_of_simple_remove(struct
-       return 0;
- }
-+#ifdef CONFIG_PM
- static int dwc3_of_simple_runtime_suspend(struct device *dev)
- {
-       struct dwc3_of_simple   *simple = dev_get_drvdata(dev);
-@@ -150,6 +151,7 @@ static int dwc3_of_simple_runtime_resume
-       return 0;
- }
-+#endif
- static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = {
-       SET_RUNTIME_PM_OPS(dwc3_of_simple_runtime_suspend,
diff --git a/target/linux/ipq806x/patches-4.4/099-usb-dwc3-Remove-impossible-check-for-of_clk_get_pare.patch b/target/linux/ipq806x/patches-4.4/099-usb-dwc3-Remove-impossible-check-for-of_clk_get_pare.patch
deleted file mode 100644 (file)
index 32f9e34..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-From 07c8b15688055d81ac8e1c8c964b9e4c302287f1 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 22 Feb 2016 11:12:47 -0800
-Subject: [PATCH] usb: dwc3: Remove impossible check for
- of_clk_get_parent_count() < 0
-
-The check for < 0 is impossible now that
-of_clk_get_parent_count() returns an unsigned int. Simplify the
-code and update the types.
-
-Acked-by: Felipe Balbi <balbi@kernel.org>
-Cc: <linux-usb@vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-(cherry picked from commit 3d755dcc20dd452b52532eca17da40ebbd12aee9)
-
-Change-Id: Iaa38e064d801fb36c855fea51c0443840368e0d3
-Signed-off-by: Nitheesh Sekar <nsekar@codeaurora.org>
----
- drivers/usb/dwc3/dwc3-of-simple.c | 9 +++++----
- 1 file changed, 5 insertions(+), 4 deletions(-)
-
---- a/drivers/usb/dwc3/dwc3-of-simple.c
-+++ b/drivers/usb/dwc3/dwc3-of-simple.c
-@@ -42,6 +42,7 @@ static int dwc3_of_simple_probe(struct p
-       struct device           *dev = &pdev->dev;
-       struct device_node      *np = dev->of_node;
-+      unsigned int            count;
-       int                     ret;
-       int                     i;
-@@ -49,11 +50,11 @@ static int dwc3_of_simple_probe(struct p
-       if (!simple)
-               return -ENOMEM;
--      ret = of_clk_get_parent_count(np);
--      if (ret < 0)
--              return ret;
-+      count = of_clk_get_parent_count(np);
-+      if (!count)
-+              return -ENOENT;
--      simple->num_clocks = ret;
-+      simple->num_clocks = count;
-       simple->clks = devm_kcalloc(dev, simple->num_clocks,
-                       sizeof(struct clk *), GFP_KERNEL);
index 6e6f10d..d1f19c3 100644 (file)
@@ -32,7 +32,7 @@
  };
 --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
 +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -333,6 +333,90 @@
+@@ -333,6 +333,88 @@
                        compatible = "syscon";
                        reg = <0x01200600 0x100>;
                };
@@ -94,7 +94,6 @@
 +                              interrupts = <0 110 0x4>;
 +                              phys = <&hs_phy_0>, <&ss_phy_0>;
 +                              phy-names = "usb2-phy", "usb3-phy";
-+                              tx-fifo-resize;
 +                              dr_mode = "host";
 +                      };
 +              };
 +                              interrupts = <0 205 0x4>;
 +                              phys = <&hs_phy_1>, <&ss_phy_1>;
 +                              phy-names = "usb2-phy", "usb3-phy";
-+                              tx-fifo-resize;
 +                              dr_mode = "host";
 +                      };
 +              };