Re: [PATCH] USB: usb.h: tweak struct urb to remove wasted space

2019-03-02 Thread Greg Kroah-Hartman
On Fri, Mar 01, 2019 at 08:44:13PM +0100, Oliver Neukum wrote:
> On Fr, 2019-03-01 at 18:22 +0100, Greg Kroah-Hartman wrote:
> > By moving one field around in 'struct urb' we reduce the size of the
> > structure by 8 bytes.
> 
> If you are going for this I have to ask why unlink and status
> are full size ints anyway.

History, they hold a "normal" negative error code.  I guess we could
turn them into s16, if it really matters, but that feels odd to me.

thanks,

greg k-h


[PATCH v3 00/12] Add support for usb on Hikey960

2019-03-02 Thread Yu Chen
The patchset adds support for usb functionality of Hikey960, includes:
- dwc3 driver for Hisilicon Kirin Soc hi3660
- usb driver for HiKey960 board
- some adjustment in dwc3, usb gadget and typec driver
- dts for support usb of HiKey960

This patchset based on patchset https://lkml.org/lkml/2019/1/25/344
of Heikki Krogerus

Yu Chen (12):
  dt-bindings: phy: Add support for HiSilicon's hi3660 USB PHY
  dt-bindings: misc: Add bindings for HiSilicon usb hub and data role
switch functionality on HiKey960
  usb: dwc3: dwc3-of-simple: Add support for dwc3 of Hisilicon Soc
Platform
  usb: dwc3: Add splitdisable quirk for Hisilicon Kirin Soc
  usb: dwc3: Execute GCTL Core Soft Reset while switch mdoe for
Hisilicon Kirin Soc
  usb: dwc3: Increase timeout for CmdAct cleared by device controller
  phy: Add usb phy support for hi3660 Soc of Hisilicon
  usb: roles: Add usb role switch notifier.
  usb: dwc3: Registering a role switch in the DRD code.
  hikey960: Support usb functionality of Hikey960
  usb: gadget: Add configfs attribuite for controling
match_existing_only
  dts: hi3660: Add support for usb on Hikey960

 .../bindings/misc/hisilicon-hikey-usb.txt  |  52 +
 .../devicetree/bindings/phy/phy-hi3660-usb3.txt|  28 +++
 MAINTAINERS|   8 +
 arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts  |  53 +
 arch/arm64/boot/dts/hisilicon/hi3660.dtsi  |  74 +++
 drivers/misc/Kconfig   |   6 +
 drivers/misc/Makefile  |   1 +
 drivers/misc/hisi_hikey_usb.c  | 167 +++
 drivers/phy/hisilicon/Kconfig  |  10 +
 drivers/phy/hisilicon/Makefile |   1 +
 drivers/phy/hisilicon/phy-hi3660-usb3.c| 232 +
 drivers/usb/dwc3/Kconfig   |   1 +
 drivers/usb/dwc3/core.c|  43 
 drivers/usb/dwc3/core.h|  10 +
 drivers/usb/dwc3/drd.c |  58 +-
 drivers/usb/dwc3/dwc3-of-simple.c  |   4 +-
 drivers/usb/dwc3/gadget.c  |   2 +-
 drivers/usb/gadget/configfs.c  |  32 +++
 drivers/usb/roles/class.c  |  20 +-
 include/linux/usb/role.h   |  46 
 20 files changed, 844 insertions(+), 4 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/misc/hisilicon-hikey-usb.txt
 create mode 100644 Documentation/devicetree/bindings/phy/phy-hi3660-usb3.txt
 create mode 100644 drivers/misc/hisi_hikey_usb.c
 create mode 100644 drivers/phy/hisilicon/phy-hi3660-usb3.c

-- 
2.15.0-rc2



[PATCH v3 12/12] dts: hi3660: Add support for usb on Hikey960

2019-03-02 Thread Yu Chen
This patch adds support for usb on Hikey960.

Cc: Chunfeng Yun 
Cc: Wei Xu 
Cc: Rob Herring 
Cc: Mark Rutland 
Cc: linux-arm-ker...@lists.infradead.org
Cc: John Stultz 
Cc: Binghui Wang 
Signed-off-by: Yu Chen 
---
v2:
* Remove device_type property.
* Add property "usb-role-switch".
v3:
* Make node "usb_phy" a subnode of usb3_otg_bc register.
* Remove property "typec-vbus-enable-val" of hisi_hikey_usb.
---
---
 arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts | 53 
 arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 74 +++
 2 files changed, 127 insertions(+)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts 
b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
index 46435466f1ab..7900ca60092e 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 
 / {
model = "HiKey960";
@@ -196,6 +197,26 @@
method = "smc";
};
};
+
+   hisi_hikey_usb: hisi_hikey_usb {
+   compatible = "hisilicon,hikey960_usb";
+   typec-vbus-gpios = <&gpio25 2 GPIO_ACTIVE_HIGH>;
+   otg-switch-gpios = <&gpio25 6 GPIO_ACTIVE_HIGH>;
+   hub-vdd33-en-gpios = <&gpio5 6 GPIO_ACTIVE_HIGH>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&usbhub5734_pmx_func>;
+
+   port {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   hikey_usb_ep: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = <&dwc3_role_switch_notify>;
+   };
+   };
+   };
+
 };
 
 /*
@@ -526,6 +547,38 @@
 &i2c1 {
status = "okay";
 
+   rt1711h: rt1711h@4e {
+   compatible = "richtek,rt1711h";
+   reg = <0x4e>;
+   status = "ok";
+   interrupt-parent = <&gpio27>;
+   interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&usb_cfg_func>;
+
+   usb_con: connector {
+   compatible = "usb-c-connector";
+   label = "USB-C";
+   data-role = "dual";
+   power-role = "dual";
+   try-power-role = "sink";
+   source-pdos = ;
+   sink-pdos = ;
+   op-sink-microwatt = <1000>;
+   };
+
+   port {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   rt1711h_ep: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = <&dwc3_role_switch>;
+   };
+   };
+   };
+
adv7533: adv7533@39 {
status = "ok";
compatible = "adi,adv7533";
diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi 
b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
index 20ae40df61d5..bfda59a41570 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
@@ -355,6 +355,12 @@
#clock-cells = <1>;
};
 
+   pmctrl: pmctrl@fff31000 {
+   compatible = "hisilicon,hi3660-pmctrl", "syscon";
+   reg = <0x0 0xfff31000 0x0 0x1000>;
+   #clock-cells = <1>;
+   };
+
pmuctrl: crg_ctrl@fff34000 {
compatible = "hisilicon,hi3660-pmuctrl", "syscon";
reg = <0x0 0xfff34000 0x0 0x1000>;
@@ -1134,5 +1140,73 @@
};
};
};
+
+   usb3_otg_bc: usb3_otg_bc@ff20 {
+   compatible = "syscon", "simple-mfd";
+   reg = <0x0 0xff20 0x0 0x1000>;
+
+   usb_phy: usb-phy {
+   compatible = "hisilicon,hi3660-usb-phy";
+   #phy-cells = <0>;
+   hisilicon,pericrg-syscon = <&crg_ctrl>;
+   hisilicon,pctrl-syscon = <&pctrl>;
+   hisilicon,usb3-otg-bc-syscon = <&usb3_otg_bc>;
+   hisilicon,eye-diagram-param = <0x22466e4>;
+   };
+   };
+
+   usb3: hisi_dwc3 {
+   compatible = "hisilicon,hi3660-dwc3";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+
+   clocks = <&crg_ctrl HI3660_CLK_ABB_USB>,
+<&crg_ctrl HI3660_ACLK_GATE_USB3OTG>;
+   clock-names = "clk_usb3phy_ref", 

[PATCH v3 10/12] hikey960: Support usb functionality of Hikey960

2019-03-02 Thread Yu Chen
This driver handles usb hub power on and typeC port event of HiKey960 board:
1)DP&DM switching between usb hub and typeC port base on typeC port
state
2)Control power of usb hub on Hikey960
3)Control vbus of typeC port

Cc: Chunfeng Yun 
Cc: Andy Shevchenko 
Cc: Arnd Bergmann 
Cc: Greg Kroah-Hartman 
Cc: John Stultz 
Cc: Binghui Wang 
Cc: Heikki Krogerus 
Signed-off-by: Yu Chen 
---
v1:
* Using gpiod API with the gpios.
* Removing registering usb role switch.
* Registering usb role switch notifier.
v2:
* Fix license declaration.
* Add configuration of  gpio direction.
* Remove some log print.
v3:
* Remove property of "typec_vbus_enable_val".
* Remove gpiod_direction_output and set initial value of gpio by devm_gpiod_get.
---
---
 drivers/misc/Kconfig  |   6 ++
 drivers/misc/Makefile |   1 +
 drivers/misc/hisi_hikey_usb.c | 167 ++
 3 files changed, 174 insertions(+)
 create mode 100644 drivers/misc/hisi_hikey_usb.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index f417b06e11c5..8d8b717759e2 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -521,6 +521,12 @@ config PVPANIC
  a paravirtualized device provided by QEMU; it lets a virtual machine
  (guest) communicate panic events to the host.
 
+config HISI_HIKEY_USB
+   tristate "USB functionality of HiSilicon Hikey Platform"
+   depends on OF && GPIOLIB
+   help
+ If you say yes here you get support for usb functionality of 
HiSilicon Hikey Platform.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index e39ccbbc1b3a..dc8892b13a1a 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -59,3 +59,4 @@ obj-$(CONFIG_PCI_ENDPOINT_TEST)   += pci_endpoint_test.o
 obj-$(CONFIG_OCXL) += ocxl/
 obj-y  += cardreader/
 obj-$(CONFIG_PVPANIC)  += pvpanic.o
+obj-$(CONFIG_HISI_HIKEY_USB)   += hisi_hikey_usb.o
diff --git a/drivers/misc/hisi_hikey_usb.c b/drivers/misc/hisi_hikey_usb.c
new file mode 100644
index ..85d6fee468c0
--- /dev/null
+++ b/drivers/misc/hisi_hikey_usb.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Support for usb functionality of Hikey series boards
+ * based on Hisilicon Kirin Soc.
+ *
+ * Copyright (C) 2017-2018 Hilisicon Electronics Co., Ltd.
+ * http://www.huawei.com
+ *
+ * Authors: Yu Chen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DEVICE_DRIVER_NAME "hisi_hikey_usb"
+
+#define HUB_VBUS_POWER_ON 1
+#define HUB_VBUS_POWER_OFF 0
+#define USB_SWITCH_TO_HUB 1
+#define USB_SWITCH_TO_TYPEC 0
+#define TYPEC_VBUS_POWER_ON 1
+#define TYPEC_VBUS_POWER_OFF 0
+
+struct hisi_hikey_usb {
+   struct gpio_desc *otg_switch;
+   struct gpio_desc *typec_vbus;
+   struct gpio_desc *hub_vbus;
+
+   struct usb_role_switch *role_sw;
+   struct notifier_block nb;
+};
+
+static void hub_power_ctrl(struct hisi_hikey_usb *hisi_hikey_usb, int value)
+{
+   gpiod_set_value_cansleep(hisi_hikey_usb->hub_vbus, value);
+}
+
+static void usb_switch_ctrl(struct hisi_hikey_usb *hisi_hikey_usb,
+   int switch_to)
+{
+   gpiod_set_value_cansleep(hisi_hikey_usb->otg_switch, switch_to);
+}
+
+static void usb_typec_power_ctrl(struct hisi_hikey_usb *hisi_hikey_usb,
+   int value)
+{
+   gpiod_set_value_cansleep(hisi_hikey_usb->typec_vbus, value);
+}
+
+static int hisi_hikey_role_switch(struct notifier_block *nb,
+   unsigned long state, void *data)
+{
+   struct hisi_hikey_usb *hisi_hikey_usb;
+
+   hisi_hikey_usb = container_of(nb, struct hisi_hikey_usb, nb);
+
+   switch (state) {
+   case USB_ROLE_NONE:
+   usb_typec_power_ctrl(hisi_hikey_usb, TYPEC_VBUS_POWER_OFF);
+   usb_switch_ctrl(hisi_hikey_usb, USB_SWITCH_TO_HUB);
+   hub_power_ctrl(hisi_hikey_usb, HUB_VBUS_POWER_ON);
+   break;
+   case USB_ROLE_HOST:
+   usb_switch_ctrl(hisi_hikey_usb, USB_SWITCH_TO_TYPEC);
+   usb_typec_power_ctrl(hisi_hikey_usb, TYPEC_VBUS_POWER_ON);
+   break;
+   case USB_ROLE_DEVICE:
+   hub_power_ctrl(hisi_hikey_usb, HUB_VBUS_POWER_OFF);
+   usb_typec_power_ctrl(hisi_hikey_usb, TYPEC_VBUS_POWER_OFF);
+   usb_switch_ctrl(hisi_hikey_usb, USB_SWITCH_TO_TYPEC);
+   break;
+   default:
+   break;
+   }
+
+   return 0;
+}
+
+static int hisi_hikey_usb_probe(struct platform_device *pdev)
+{
+   struct device *dev = &pdev->dev;
+   struct device_node *root = dev->of_node;
+   struct hisi_hikey_usb *hisi_hikey_usb;
+   int ret;
+
+   hisi_hikey_usb = devm_kzalloc(dev, sizeof(*hisi_hikey_usb), GFP_KERNEL);
+   if (!hisi_hikey_usb)
+

[PATCH v3 11/12] usb: gadget: Add configfs attribuite for controling match_existing_only

2019-03-02 Thread Yu Chen
Currently the "match_existing_only" of usb_gadget_driver in configfs is
set to one which is not flexible.
Dwc3 udc will be removed when usb core switch to host mode. This causes
failure of writing name of dwc3 udc to configfs's UDC attribuite.
To fix this we need to add a way to change the config of
"match_existing_only".
There are systems like Android do not support udev, so adding
"match_existing_only" attribute to allow configuration by user is cost little.
This patch adds a configfs attribuite for controling match_existing_only
which allow user to config "match_existing_only".

Cc: Andy Shevchenko 
Cc: Felipe Balbi 
Cc: Greg Kroah-Hartman 
Cc: John Stultz 
Cc: Binghui Wang 
Signed-off-by: Yu Chen 
---
 drivers/usb/gadget/configfs.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 025129942894..be85104bfab9 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -291,6 +291,36 @@ static ssize_t gadget_dev_desc_UDC_store(struct 
config_item *item,
return ret;
 }
 
+static ssize_t gadget_driver_match_existing_only_store(struct config_item 
*item,
+   const char *page, size_t len)
+{
+   struct gadget_info *gi = to_gadget_info(item);
+   struct usb_gadget_driver *gadget_driver = 
&(gi->composite.gadget_driver);
+   bool match_existing_only;
+   int ret;
+
+   ret = kstrtobool(page, &match_existing_only);
+   if (ret)
+   return ret;
+
+   if (match_existing_only)
+   gadget_driver->match_existing_only = 1;
+   else
+   gadget_driver->match_existing_only = 0;
+
+   return len;
+}
+
+static ssize_t gadget_driver_match_existing_only_show(struct config_item *item,
+   char *page)
+{
+   struct gadget_info *gi = to_gadget_info(item);
+   struct usb_gadget_driver *gadget_driver = 
&(gi->composite.gadget_driver);
+   bool match_existing_only = !!gadget_driver->match_existing_only;
+
+   return sprintf(page, "%s\n", match_existing_only ? "true" : "false");
+}
+
 CONFIGFS_ATTR(gadget_dev_desc_, bDeviceClass);
 CONFIGFS_ATTR(gadget_dev_desc_, bDeviceSubClass);
 CONFIGFS_ATTR(gadget_dev_desc_, bDeviceProtocol);
@@ -300,6 +330,7 @@ CONFIGFS_ATTR(gadget_dev_desc_, idProduct);
 CONFIGFS_ATTR(gadget_dev_desc_, bcdDevice);
 CONFIGFS_ATTR(gadget_dev_desc_, bcdUSB);
 CONFIGFS_ATTR(gadget_dev_desc_, UDC);
+CONFIGFS_ATTR(gadget_, driver_match_existing_only);
 
 static struct configfs_attribute *gadget_root_attrs[] = {
&gadget_dev_desc_attr_bDeviceClass,
@@ -311,6 +342,7 @@ static struct configfs_attribute *gadget_root_attrs[] = {
&gadget_dev_desc_attr_bcdDevice,
&gadget_dev_desc_attr_bcdUSB,
&gadget_dev_desc_attr_UDC,
+   &gadget_attr_driver_match_existing_only,
NULL,
 };
 
-- 
2.15.0-rc2



[PATCH v3 02/12] dt-bindings: misc: Add bindings for HiSilicon usb hub and data role switch functionality on HiKey960

2019-03-02 Thread Yu Chen
This patch adds binding documentation to support usb hub and usb
data role switch of Hisilicon HiKey960 Board.

Cc: Sergei Shtylyov 
Cc: Rob Herring 
Cc: Mark Rutland 
Cc: John Stultz 
Cc: Binghui Wang 
Signed-off-by: Yu Chen 
---
v1:
* Fix some format errors as suggested by Sergei.
* Modify gpio description to use gpiod API.
v2:
* Remove information about Hikey.
* Fix gpio description.
* Remove device_type of endpoint.
v3:
* Remove property typec-vbus-enable-val.
* Add description of pinctrl-names.
* Add example for "hisilicon,gpio-hubv1"
* Add flag in gpiod properties.
---
---
 .../bindings/misc/hisilicon-hikey-usb.txt  | 52 ++
 1 file changed, 52 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/misc/hisilicon-hikey-usb.txt

diff --git a/Documentation/devicetree/bindings/misc/hisilicon-hikey-usb.txt 
b/Documentation/devicetree/bindings/misc/hisilicon-hikey-usb.txt
new file mode 100644
index ..422e844df719
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/hisilicon-hikey-usb.txt
@@ -0,0 +1,52 @@
+Support usb hub and usb data role switch of Hisilicon HiKey960 Board.
+
+-
+
+Required properties:
+- compatible: "hisilicon,gpio-hubv1","hisilicon,hikey960-usb"
+- typec-vbus-gpios: gpio to control the vbus of typeC port
+- otg-switch-gpios: gpio to switch DP & DM between the hub and typeC port
+- hub-vdd33-en-gpios: gpio to enable the power of hub
+- pinctrl-names: pin configuration state name ("default")
+- pinctrl-0: pinctrl config
+
+Example
+-
+
+   hisi_hikey_usb: hisi_hikey_usb {
+   compatible = "hisilicon,hikey960-usb";
+   typec-vbus-gpios = <&gpio25 2 GPIO_ACTIVE_HIGH>;
+   otg-switch-gpios = <&gpio25 6 GPIO_ACTIVE_HIGH>;
+   hub-vdd33-en-gpios = <&gpio5 6 GPIO_ACTIVE_HIGH>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&usbhub5734_pmx_func>;
+
+   port {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   hikey_usb_ep: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = <&dwc3_role_switch_notify>;
+   };
+   };
+   };
+
+   hisi_hikey_usb: hisi_hikey_usb {
+   compatible = "hisilicon,gpio-hubv1";
+   typec-vbus-gpios = <&gpio25 2 GPIO_ACTIVE_LOW>;
+   otg-switch-gpios = <&gpio25 6 GPIO_ACTIVE_HIGH>;
+   hub-vdd33-en-gpios = <&gpio5 6 GPIO_ACTIVE_HIGH>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&usbhub5734_pmx_func>;
+
+   port {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   hikey_usb_ep: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = <&dwc3_role_switch_notify>;
+   };
+   };
+   };
-- 
2.15.0-rc2



[PATCH v3 08/12] usb: roles: Add usb role switch notifier.

2019-03-02 Thread Yu Chen
This patch adds notifier for drivers want to be informed of the usb role switch.

Cc: Greg Kroah-Hartman 
Cc: Heikki Krogerus 
Cc: Hans de Goede 
Cc: Andy Shevchenko 
Cc: John Stultz 
Suggested-by: Heikki Krogerus 
Signed-off-by: Yu Chen 
---
 drivers/usb/roles/class.c | 20 +++-
 include/linux/usb/role.h  | 46 ++
 2 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c
index f45d8df5cfb8..e2caaa665d6e 100644
--- a/drivers/usb/roles/class.c
+++ b/drivers/usb/roles/class.c
@@ -20,6 +20,7 @@ struct usb_role_switch {
struct device dev;
struct mutex lock; /* device lock*/
enum usb_role role;
+   struct blocking_notifier_head nh;
 
/* From descriptor */
struct device *usb2_port;
@@ -49,8 +50,10 @@ int usb_role_switch_set_role(struct usb_role_switch *sw, 
enum usb_role role)
mutex_lock(&sw->lock);
 
ret = sw->set(sw->dev.parent, role);
-   if (!ret)
+   if (!ret) {
sw->role = role;
+   blocking_notifier_call_chain(&sw->nh, role, NULL);
+   }
 
mutex_unlock(&sw->lock);
 
@@ -58,6 +61,20 @@ int usb_role_switch_set_role(struct usb_role_switch *sw, 
enum usb_role role)
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_set_role);
 
+int usb_role_switch_register_notifier(struct usb_role_switch *sw,
+ struct notifier_block *nb)
+{
+   return blocking_notifier_chain_register(&sw->nh, nb);
+}
+EXPORT_SYMBOL_GPL(usb_role_switch_register_notifier);
+
+int usb_role_switch_unregister_notifier(struct usb_role_switch *sw,
+   struct notifier_block *nb)
+{
+   return blocking_notifier_chain_unregister(&sw->nh, nb);
+}
+EXPORT_SYMBOL_GPL(usb_role_switch_unregister_notifier);
+
 /**
  * usb_role_switch_get_role - Get the USB role for a switch
  * @sw: USB role switch
@@ -271,6 +288,7 @@ usb_role_switch_register(struct device *parent,
return ERR_PTR(-ENOMEM);
 
mutex_init(&sw->lock);
+   BLOCKING_INIT_NOTIFIER_HEAD(&sw->nh);
 
sw->allow_userspace_control = desc->allow_userspace_control;
sw->usb2_port = desc->usb2_port;
diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h
index 9684a8734757..9e1ca663387a 100644
--- a/include/linux/usb/role.h
+++ b/include/linux/usb/role.h
@@ -41,6 +41,8 @@ struct usb_role_switch_desc {
bool allow_userspace_control;
 };
 
+
+#if IS_ENABLED(CONFIG_USB_ROLE_SWITCH)
 int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role);
 enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw);
 struct usb_role_switch *usb_role_switch_get(struct device *dev);
@@ -50,5 +52,49 @@ struct usb_role_switch *
 usb_role_switch_register(struct device *parent,
 const struct usb_role_switch_desc *desc);
 void usb_role_switch_unregister(struct usb_role_switch *sw);
+int usb_role_switch_register_notifier(struct usb_role_switch *sw,
+ struct notifier_block *nb);
+int usb_role_switch_unregister_notifier(struct usb_role_switch *sw,
+   struct notifier_block *nb);
+#else
+static inline int usb_role_switch_set_role(struct usb_role_switch *sw,
+   enum usb_role role)
+{
+   return 0;
+}
+
+static inline enum usb_role usb_role_switch_get_role(struct usb_role_switch 
*sw)
+{
+   return USB_ROLE_NONE;
+}
+
+static inline struct usb_role_switch *usb_role_switch_get(struct device *dev)
+{
+   return ERR_PTR(-ENODEV);
+}
+
+static inline void usb_role_switch_put(struct usb_role_switch *sw) { }
+
+static inline struct usb_role_switch *
+usb_role_switch_register(struct device *parent,
+const struct usb_role_switch_desc *desc)
+{
+   return ERR_PTR(-ENODEV);
+}
+
+static inline void usb_role_switch_unregister(struct usb_role_switch *sw) { }
+
+static int usb_role_switch_register_notifier(struct usb_role_switch *sw,
+ struct notifier_block *nb)
+{
+   return -ENODEV;
+}
+
+static int usb_role_switch_unregister_notifier(struct usb_role_switch *sw,
+   struct notifier_block *nb)
+{
+   return -ENODEV;
+}
+#endif
 
 #endif /* __LINUX_USB_ROLE_H */
-- 
2.15.0-rc2



[PATCH v3 07/12] phy: Add usb phy support for hi3660 Soc of Hisilicon

2019-03-02 Thread Yu Chen
This driver handles usb phy power on and shutdown for hi3660 Soc of
Hisilicon.

Cc: Andy Shevchenko 
Cc: Kishon Vijay Abraham I 
Cc: "David S. Miller" 
Cc: Greg Kroah-Hartman 
Cc: Mauro Carvalho Chehab 
Cc: Andrew Morton 
Cc: Arnd Bergmann 
Cc: Shawn Guo 
Cc: Pengcheng Li 
Cc: Jianguo Sun 
Cc: Masahiro Yamada 
Cc: Jiancheng Xue 
Cc: John Stultz 
Cc: Binghui Wang 
Signed-off-by: Yu Chen 
---
v1:
* Remove unused code and add comment for time delay as suggested by
Kishon Vijay Abraham I.
v2:
* Fix license declaration.
* Remove redundant parens.
* Remove unused member variables in struct hi3660_priv.
---
---
 MAINTAINERS |   8 ++
 drivers/phy/hisilicon/Kconfig   |  10 ++
 drivers/phy/hisilicon/Makefile  |   1 +
 drivers/phy/hisilicon/phy-hi3660-usb3.c | 232 
 4 files changed, 251 insertions(+)
 create mode 100644 drivers/phy/hisilicon/phy-hi3660-usb3.c

diff --git a/MAINTAINERS b/MAINTAINERS
index dce5c099f43c..ac2e518ab85f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15822,6 +15822,14 @@ L: linux-usb@vger.kernel.org
 S: Maintained
 F: drivers/usb/roles/intel-xhci-usb-role-switch.c
 
+USB IP DRIVER FOR HISILICON KIRIN
+M: Yu Chen 
+M: Binghui Wang 
+L: linux-usb@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/phy/phy-hi3660-usb3.txt
+F: drivers/phy/hisilicon/phy-hi3660-usb3.c
+
 USB ISP116X DRIVER
 M: Olav Kongas 
 L: linux-usb@vger.kernel.org
diff --git a/drivers/phy/hisilicon/Kconfig b/drivers/phy/hisilicon/Kconfig
index b40ee54a1a50..3c142f08987c 100644
--- a/drivers/phy/hisilicon/Kconfig
+++ b/drivers/phy/hisilicon/Kconfig
@@ -12,6 +12,16 @@ config PHY_HI6220_USB
 
  To compile this driver as a module, choose M here.
 
+config PHY_HI3660_USB
+   tristate "hi3660 USB PHY support"
+   depends on (ARCH_HISI && ARM64) || COMPILE_TEST
+   select GENERIC_PHY
+   select MFD_SYSCON
+   help
+ Enable this to support the HISILICON HI3660 USB PHY.
+
+ To compile this driver as a module, choose M here.
+
 config PHY_HISTB_COMBPHY
tristate "HiSilicon STB SoCs COMBPHY support"
depends on (ARCH_HISI && ARM64) || COMPILE_TEST
diff --git a/drivers/phy/hisilicon/Makefile b/drivers/phy/hisilicon/Makefile
index f662a4fe18d8..75ba64e2faf8 100644
--- a/drivers/phy/hisilicon/Makefile
+++ b/drivers/phy/hisilicon/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_PHY_HI6220_USB)   += phy-hi6220-usb.o
+obj-$(CONFIG_PHY_HI3660_USB)   += phy-hi3660-usb3.o
 obj-$(CONFIG_PHY_HISTB_COMBPHY)+= phy-histb-combphy.o
 obj-$(CONFIG_PHY_HISI_INNO_USB2)   += phy-hisi-inno-usb2.o
 obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o
diff --git a/drivers/phy/hisilicon/phy-hi3660-usb3.c 
b/drivers/phy/hisilicon/phy-hi3660-usb3.c
new file mode 100644
index ..97184e6f0d41
--- /dev/null
+++ b/drivers/phy/hisilicon/phy-hi3660-usb3.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Phy provider for USB 3.0 controller on HiSilicon 3660 platform
+ *
+ * Copyright (C) 2017-2018 Hilisicon Electronics Co., Ltd.
+ * http://www.huawei.com
+ *
+ * Authors: Yu Chen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PERI_CRG_CLK_EN4   0x40
+#define PERI_CRG_CLK_DIS4  0x44
+#define GT_CLK_USB3OTG_REF BIT(0)
+#define GT_ACLK_USB3OTGBIT(1)
+
+#define PERI_CRG_RSTEN40x90
+#define PERI_CRG_RSTDIS4   0x94
+#define IP_RST_USB3OTGPHY_POR  BIT(3)
+#define IP_RST_USB3OTG BIT(5)
+
+#define PERI_CRG_ISODIS0x148
+#define USB_REFCLK_ISO_EN  BIT(25)
+
+#define PCTRL_PERI_CTRL3   0x10
+#define PCTRL_PERI_CTRL3_MSK_START 16
+#define USB_TCXO_ENBIT(1)
+
+#define PCTRL_PERI_CTRL24  0x64
+#define SC_CLK_USB3PHY_3MUX1_SEL   BIT(25)
+
+#define USBOTG3_CTRL0  0x00
+#define SC_USB3PHY_ABB_GT_EN   BIT(15)
+
+#define USBOTG3_CTRL2  0x08
+#define USBOTG3CTRL2_POWERDOWN_HSP BIT(0)
+#define USBOTG3CTRL2_POWERDOWN_SSP BIT(1)
+
+#define USBOTG3_CTRL3  0x0C
+#define USBOTG3_CTRL3_VBUSVLDEXT   BIT(6)
+#define USBOTG3_CTRL3_VBUSVLDEXTSELBIT(5)
+
+#define USBOTG3_CTRL4  0x10
+
+#define USBOTG3_CTRL7  0x1c
+#define REF_SSP_EN BIT(16)
+
+#define HI3660_USB_DEFAULT_PHY_PARAM   0x1c466e3
+
+struct hi3660_priv {
+   struct device *dev;
+   struct regmap *peri_crg;
+   struct regmap *pctrl;
+   struct regmap *otg_bc;
+   u32 eye_diagram_param;

[PATCH v3 09/12] usb: dwc3: Registering a role switch in the DRD code.

2019-03-02 Thread Yu Chen
The Type-C drivers use USB role switch API to inform the
system about the negotiated data role, so registering a role
switch in the DRD code in order to support platforms with
USB Type-C connectors.

Cc: Jun Li 
Cc: Valentin Schneider 
Cc: John Stultz 
Cc: Felipe Balbi 
Cc: Greg Kroah-Hartman 
Cc: Heikki Krogerus 
Suggested-by: Heikki Krogerus 
Signed-off-by: Yu Chen 
---
v2:
* Assign fwnode in dwc3_role_switch.
v3:
* Add default mode property for usb role switch.
* Add select USB_ROLE_SWITCH for USB_DWC3_DUAL_ROLE in Kconfig.
* Do usb_role_switch_register only if property "usb-role-switch" present.
---
---
 drivers/usb/dwc3/Kconfig |  1 +
 drivers/usb/dwc3/core.h  |  3 +++
 drivers/usb/dwc3/drd.c   | 58 +++-
 3 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index 1a0404fda596..3a0cb9f1f38a 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -42,6 +42,7 @@ config USB_DWC3_DUAL_ROLE
bool "Dual Role mode"
depends on ((USB=y || USB=USB_DWC3) && (USB_GADGET=y || 
USB_GADGET=USB_DWC3))
depends on (EXTCON=y || EXTCON=USB_DWC3)
+   select USB_ROLE_SWITCH
help
  This is the default mode of working of DWC3 controller where
  both host and gadget features are enabled.
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 402b3c29eb26..b2b0da007bff 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -1083,6 +1084,8 @@ struct dwc3 {
struct extcon_dev   *edev;
struct notifier_block   edev_nb;
enum usb_phy_interface  hsphy_mode;
+   struct usb_role_switch  *role_sw;
+   enum usb_dr_moderole_switch_default_mode;
 
u32 fladj;
u32 irq_gadget;
diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
index 869725d15c74..5bfea03233d7 100644
--- a/drivers/usb/dwc3/drd.c
+++ b/drivers/usb/dwc3/drd.c
@@ -474,6 +474,43 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
return edev;
 }
 
+static int dwc3_usb_role_switch_set(struct device *dev, enum usb_role role)
+{
+   struct dwc3 *dwc = dev_get_drvdata(dev);
+   u32 mode;
+
+   switch (role) {
+   case USB_ROLE_HOST:
+   mode = DWC3_GCTL_PRTCAP_HOST;
+   break;
+   case USB_ROLE_DEVICE:
+   mode = DWC3_GCTL_PRTCAP_DEVICE;
+   break;
+   default:
+   if (dwc->role_switch_default_mode == USB_DR_MODE_HOST)
+   mode = DWC3_GCTL_PRTCAP_HOST;
+   else
+   mode = DWC3_GCTL_PRTCAP_DEVICE;
+   break;
+   }
+
+   dwc3_set_mode(dwc, mode);
+   return 0;
+}
+
+static enum usb_role dwc3_usb_role_switch_get(struct device *dev)
+{
+   struct dwc3 *dwc = dev_get_drvdata(dev);
+   unsigned long flags;
+   enum usb_role role;
+
+   spin_lock_irqsave(&dwc->lock, flags);
+   role = dwc->current_otg_role;
+   spin_unlock_irqrestore(&dwc->lock, flags);
+
+   return role;
+}
+
 int dwc3_drd_init(struct dwc3 *dwc)
 {
int ret, irq;
@@ -482,7 +519,23 @@ int dwc3_drd_init(struct dwc3 *dwc)
if (IS_ERR(dwc->edev))
return PTR_ERR(dwc->edev);
 
-   if (dwc->edev) {
+   if (device_property_read_bool(dwc->dev, "usb-role-switch")) {
+   struct usb_role_switch_desc dwc3_role_switch = {0};
+
+   if (device_property_read_bool(dwc->dev,
+   "role-switch-default-host"))
+   dwc->role_switch_default_mode = USB_DR_MODE_HOST;
+   else
+   dwc->role_switch_default_mode = USB_DR_MODE_PERIPHERAL;
+
+   dwc3_role_switch.fwnode = dev_fwnode(dwc->dev);
+   dwc3_role_switch.set = dwc3_usb_role_switch_set;
+   dwc3_role_switch.get = dwc3_usb_role_switch_get;
+   dwc->role_sw = usb_role_switch_register(dwc->dev,
+   &dwc3_role_switch);
+   if (IS_ERR(dwc->role_sw))
+   return PTR_ERR(dwc->role_sw);
+   } else if (dwc->edev) {
dwc->edev_nb.notifier_call = dwc3_drd_notifier;
ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST,
   &dwc->edev_nb);
@@ -529,6 +582,9 @@ void dwc3_drd_exit(struct dwc3 *dwc)
 {
unsigned long flags;
 
+   if (dwc->role_sw)
+   usb_role_switch_unregister(dwc->role_sw);
+
if (dwc->edev)
extcon_unregister_notifier(dwc->edev, EXTCON_USB_HOST,
   &dwc->edev_nb);
-- 
2.15.0-rc2



[PATCH v3 05/12] usb: dwc3: Execute GCTL Core Soft Reset while switch mdoe for Hisilicon Kirin Soc

2019-03-02 Thread Yu Chen
A GCTL soft reset should be executed when switch mode for dwc3 core
of Hisilicon Kirin Soc.

Cc: Andy Shevchenko 
Cc: Felipe Balbi 
Cc: Greg Kroah-Hartman 
Cc: John Stultz 
Cc: Binghui Wang 
Signed-off-by: Yu Chen 
---
 drivers/usb/dwc3/core.c | 19 +++
 drivers/usb/dwc3/core.h |  1 +
 2 files changed, 20 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index f7d561fe1f04..f260977f0206 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -112,6 +112,19 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
dwc->current_dr_role = mode;
 }
 
+static void dwc3_gctl_core_soft_reset(struct dwc3 *dwc)
+{
+   u32 reg;
+
+   reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+   reg |= DWC3_GCTL_CORESOFTRESET;
+   dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+
+   reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+   reg &= ~DWC3_GCTL_CORESOFTRESET;
+   dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+}
+
 static void __dwc3_set_mode(struct work_struct *work)
 {
struct dwc3 *dwc = work_to_dwc(work);
@@ -157,6 +170,10 @@ static void __dwc3_set_mode(struct work_struct *work)
 
dwc3_set_prtcap(dwc, dwc->desired_dr_role);
 
+   /* Execute a GCTL Core Soft Reset when switch mode */
+   if (dwc->gctl_reset_quirk)
+   dwc3_gctl_core_soft_reset(dwc);
+
spin_unlock_irqrestore(&dwc->lock, flags);
 
switch (dwc->desired_dr_role) {
@@ -1314,6 +1331,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
 
dwc->dis_split_quirk = device_property_read_bool(dev,
"snps,dis-split-quirk");
+   dwc->gctl_reset_quirk = device_property_read_bool(dev,
+   "snps,gctl-reset-quirk");
 
dwc->lpm_nyet_threshold = lpm_nyet_threshold;
dwc->tx_de_emphasis = tx_de_emphasis;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index bc2a1ebc0076..402b3c29eb26 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1215,6 +1215,7 @@ struct dwc3 {
unsigneddis_metastability_quirk:1;
 
unsigneddis_split_quirk:1;
+   unsignedgctl_reset_quirk:1;
 
u16 imod_interval;
 };
-- 
2.15.0-rc2



[PATCH v3 01/12] dt-bindings: phy: Add support for HiSilicon's hi3660 USB PHY

2019-03-02 Thread Yu Chen
This patch adds binding documentation for supporting the hi3660 usb
phy on boards like the HiKey960.

Cc: Rob Herring 
Cc: Mark Rutland 
Cc: John Stultz 
Cc: Binghui Wang 
Signed-off-by: Yu Chen 
---
v1:
* Fix some format error as suggested by Rob.
v2:
* Change hi3660 usb PHY to hi3660 USB PHY
v3:
* Make device node a subnode of usb3_otg_bc register.
---
---
 .../devicetree/bindings/phy/phy-hi3660-usb3.txt| 28 ++
 1 file changed, 28 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-hi3660-usb3.txt

diff --git a/Documentation/devicetree/bindings/phy/phy-hi3660-usb3.txt 
b/Documentation/devicetree/bindings/phy/phy-hi3660-usb3.txt
new file mode 100644
index ..6096214a2bc6
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-hi3660-usb3.txt
@@ -0,0 +1,28 @@
+Hisilicon hi3660 USB PHY
+---
+
+Required properties:
+- compatible: should be "hisilicon,hi3660-usb-phy"
+- #phy-cells: must be 0
+- hisilicon,pericrg-syscon: phandle of syscon used to control phy.
+- hisilicon,pctrl-syscon: phandle of syscon used to control phy.
+- hisilicon,usb3-otg-bc-syscon: phandle of syscon used to control phy.
+- hisilicon,eye-diagram-param: parameter set for phy
+Refer to phy/phy-bindings.txt for the generic PHY binding properties
+
+This is a subnode of usb3_otg_bc register node.
+
+Example:
+   usb3_otg_bc: usb3_otg_bc@ff20 {
+   compatible = "syscon", "simple-mfd";
+   reg = <0x0 0xff20 0x0 0x1000>;
+
+   usb-phy {
+   compatible = "hisilicon,hi3660-usb-phy";
+   #phy-cells = <0>;
+   hisilicon,pericrg-syscon = <&crg_ctrl>;
+   hisilicon,pctrl-syscon = <&pctrl>;
+   hisilicon,usb3-otg-bc-syscon = <&usb3_otg_bc>;
+   hisilicon,eye-diagram-param = <0x22466e4>;
+   };
+   };
-- 
2.15.0-rc2



[PATCH v3 06/12] usb: dwc3: Increase timeout for CmdAct cleared by device controller

2019-03-02 Thread Yu Chen
It needs more time for the device controller to clear the CmdAct of
DEPCMD on Hisilicon Kirin Soc.

Cc: Andy Shevchenko 
Cc: Felipe Balbi 
Cc: Greg Kroah-Hartman 
Cc: John Stultz 
Cc: Binghui Wang 
Signed-off-by: Yu Chen 
---
 drivers/usb/dwc3/gadget.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 6c9b76bcc2e1..84d701b37171 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -270,7 +270,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned 
cmd,
 {
const struct usb_endpoint_descriptor *desc = dep->endpoint.desc;
struct dwc3 *dwc = dep->dwc;
-   u32 timeout = 1000;
+   u32 timeout = 5000;
u32 saved_config = 0;
u32 reg;
 
-- 
2.15.0-rc2



[PATCH v3 03/12] usb: dwc3: dwc3-of-simple: Add support for dwc3 of Hisilicon Soc Platform

2019-03-02 Thread Yu Chen
This patch adds support for the poweron and shutdown of dwc3 core
on Hisilicon Soc Platform.
---
 drivers/usb/dwc3/dwc3-of-simple.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
b/drivers/usb/dwc3/dwc3-of-simple.c
index 4c2771c5e727..0ed09d876542 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -98,7 +98,8 @@ static int dwc3_of_simple_probe(struct platform_device *pdev)
 * Some controllers need to toggle the usb3-otg reset before trying to
 * initialize the PHY, otherwise the PHY times out.
 */
-   if (of_device_is_compatible(np, "rockchip,rk3399-dwc3"))
+   if (of_device_is_compatible(np, "rockchip,rk3399-dwc3") ||
+   of_device_is_compatible(np, "hisilicon,hi3660-dwc3"))
simple->need_reset = true;
 
if (of_device_is_compatible(np, "amlogic,meson-axg-dwc3") ||
@@ -243,6 +244,7 @@ static const struct of_device_id of_dwc3_simple_match[] = {
{ .compatible = "amlogic,meson-axg-dwc3" },
{ .compatible = "amlogic,meson-gxl-dwc3" },
{ .compatible = "allwinner,sun50i-h6-dwc3" },
+   { .compatible = "hisilicon,hi3660-dwc3" },
{ /* Sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, of_dwc3_simple_match);
-- 
2.15.0-rc2



[PATCH v3 04/12] usb: dwc3: Add splitdisable quirk for Hisilicon Kirin Soc

2019-03-02 Thread Yu Chen
SPLIT_BOUNDARY_DISABLE should be set for DesignWare USB3 DRD Core
of Hisilicon Kirin Soc when dwc3 core act as host.

Cc: Andy Shevchenko 
Cc: Felipe Balbi 
Cc: Greg Kroah-Hartman 
Cc: John Stultz 
Cc: Binghui Wang 
Signed-off-by: Yu Chen 
---
 drivers/usb/dwc3/core.c | 24 
 drivers/usb/dwc3/core.h |  6 ++
 2 files changed, 30 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index a1b126f90261..f7d561fe1f04 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -117,6 +117,7 @@ static void __dwc3_set_mode(struct work_struct *work)
struct dwc3 *dwc = work_to_dwc(work);
unsigned long flags;
int ret;
+   u32 reg;
 
if (dwc->dr_mode != USB_DR_MODE_OTG)
return;
@@ -169,6 +170,11 @@ static void __dwc3_set_mode(struct work_struct *work)
phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST);
phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST);
phy_calibrate(dwc->usb2_generic_phy);
+   if (dwc->dis_split_quirk) {
+   reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
+   reg |= DWC3_GUCTL3_SPLITDISABLE;
+   dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
+   }
}
break;
case DWC3_GCTL_PRTCAP_DEVICE:
@@ -1306,6 +1312,9 @@ static void dwc3_get_properties(struct dwc3 *dwc)
dwc->dis_metastability_quirk = device_property_read_bool(dev,
"snps,dis_metastability_quirk");
 
+   dwc->dis_split_quirk = device_property_read_bool(dev,
+   "snps,dis-split-quirk");
+
dwc->lpm_nyet_threshold = lpm_nyet_threshold;
dwc->tx_de_emphasis = tx_de_emphasis;
 
@@ -1825,10 +1834,25 @@ static int dwc3_resume(struct device *dev)
 
return 0;
 }
+
+static void dwc3_complete(struct device *dev)
+{
+   struct dwc3 *dwc = dev_get_drvdata(dev);
+   u32 reg;
+
+   if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST &&
+   dwc->dis_split_quirk) {
+   dev_dbg(dwc->dev, "set DWC3_GUCTL3_SPLITDISABLE\n");
+   reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
+   reg |= DWC3_GUCTL3_SPLITDISABLE;
+   dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
+   }
+}
 #endif /* CONFIG_PM_SLEEP */
 
 static const struct dev_pm_ops dwc3_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume)
+   .complete = dwc3_complete,
SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume,
dwc3_runtime_idle)
 };
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index df876418cb78..bc2a1ebc0076 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -136,6 +136,7 @@
 #define DWC3_GEVNTCOUNT(n) (0xc40c + ((n) * 0x10))
 
 #define DWC3_GHWPARAMS80xc600
+#define DWC3_GUCTL30xc60c
 #define DWC3_GFLADJ0xc630
 
 /* Device Registers */
@@ -370,6 +371,9 @@
 /* Global User Control Register 2 */
 #define DWC3_GUCTL2_RST_ACTBITLATERBIT(14)
 
+/* Global User Control Register 3 */
+#define DWC3_GUCTL3_SPLITDISABLE   BIT(14)
+
 /* Device Configuration Register */
 #define DWC3_DCFG_DEVADDR(addr)((addr) << 3)
 #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f)
@@ -1210,6 +1214,8 @@ struct dwc3 {
 
unsigneddis_metastability_quirk:1;
 
+   unsigneddis_split_quirk:1;
+
u16 imod_interval;
 };
 
-- 
2.15.0-rc2



Re: [PATCH 8/8] usb: dwc3: Add Amlogic G12A DWC3 glue

2019-03-02 Thread Martin Blumenstingl
Hi Neil,

> > +static int dwc3_meson_g12a_debugfs_init(struct dwc3_meson_g12a *priv)
> > +{
> > +   priv->root = debugfs_create_dir("dwc3-meson-g12a", NULL);
> > +   if (IS_ERR(priv->root))
> > +   return PTR_ERR(priv->root);
> > +
> > +   debugfs_create_file("mode_force", 0600, priv->root, priv,
> > +   &dwc3_meson_g12a_mode_force_fops);
> > +
> > +   debugfs_create_file("otg_id", 0400, priv->root, priv,
> > +   &dwc3_meson_g12a_otg_id_fops);
> > +
> > +   return 0;
> > +}
I just stumbled across the "USB role switch framework", see [0]
it seems to provide a userspace API as well and two in-kernel drivers
are using this framework already
(drivers/usb/gadget/udc/renesas_usb3.c,
drivers/usb/roles/intel-xhci-usb-role-switch.c)


[0] 
https://elixir.bootlin.com/linux/v5.0-rc8/source/drivers/usb/roles/class.c#L246


[PATCH] USB: serial: option: Add support for Quectel EM12

2019-03-02 Thread Kristian Evensen
The Quectel EM12 is a Cat. 12 LTE modem. It behaves in the exactly the
same way as the EP06 (including the dynamic configuration behavior), so
the same checkes on reserved interfaces, etc. are needed.

Signed-off-by: Kristian Evensen 
---
 drivers/usb/serial/option.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index aef15497ff31..cc8932658e72 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -246,6 +246,7 @@ static void option_instat_callback(struct urb *urb);
 #define QUECTEL_PRODUCT_EC25   0x0125
 #define QUECTEL_PRODUCT_BG96   0x0296
 #define QUECTEL_PRODUCT_EP06   0x0306
+#define QUECTEL_PRODUCT_EM12   0x0512
 
 #define CMOTECH_VENDOR_ID  0x16d8
 #define CMOTECH_PRODUCT_6001   0x6001
@@ -1086,7 +1087,10 @@ static const struct usb_device_id option_ids[] = {
  .driver_info = RSVD(4) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),
  .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
+   { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff),
+ .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
+   { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EM12, 0xff, 0, 0) },
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
-- 
2.19.1



Re: [PATCH] USB: usb.h: tweak struct urb to remove wasted space

2019-03-02 Thread Oliver Neukum
On Sa, 2019-03-02 at 09:00 +0100, Greg Kroah-Hartman wrote:
> On Fri, Mar 01, 2019 at 08:44:13PM +0100, Oliver Neukum wrote:
> > On Fr, 2019-03-01 at 18:22 +0100, Greg Kroah-Hartman wrote:
> > > By moving one field around in 'struct urb' we reduce the size of the
> > > structure by 8 bytes.
> > 
> > If you are going for this I have to ask why unlink and status
> > are full size ints anyway.
> 
> History, they hold a "normal" negative error code.  I guess we could
> turn them into s16, if it really matters, but that feels odd to me.

Returning internal error codes to user space is a bug.

Regards
Oliver



Re: [PATCH] USB: usb.h: tweak struct urb to remove wasted space

2019-03-02 Thread Greg Kroah-Hartman
On Sat, Mar 02, 2019 at 02:51:41PM +0100, Oliver Neukum wrote:
> On Sa, 2019-03-02 at 09:00 +0100, Greg Kroah-Hartman wrote:
> > On Fri, Mar 01, 2019 at 08:44:13PM +0100, Oliver Neukum wrote:
> > > On Fr, 2019-03-01 at 18:22 +0100, Greg Kroah-Hartman wrote:
> > > > By moving one field around in 'struct urb' we reduce the size of the
> > > > structure by 8 bytes.
> > > 
> > > If you are going for this I have to ask why unlink and status
> > > are full size ints anyway.
> > 
> > History, they hold a "normal" negative error code.  I guess we could
> > turn them into s16, if it really matters, but that feels odd to me.
> 
> Returning internal error codes to user space is a bug.

Where does status and unlink end up going to userspace?  Maybe through
usbfs?

confused,

greg k-h


Re: [PATCH v3 06/12] usb: dwc3: Increase timeout for CmdAct cleared by device controller

2019-03-02 Thread Andy Shevchenko
On Sat, Mar 2, 2019 at 11:06 AM Yu Chen  wrote:
>
> It needs more time for the device controller to clear the CmdAct of
> DEPCMD on Hisilicon Kirin Soc.
>

5x times more? Can you provide more specific details on that?

> Cc: Andy Shevchenko 
> Cc: Felipe Balbi 
> Cc: Greg Kroah-Hartman 
> Cc: John Stultz 
> Cc: Binghui Wang 
> Signed-off-by: Yu Chen 
> ---
>  drivers/usb/dwc3/gadget.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 6c9b76bcc2e1..84d701b37171 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -270,7 +270,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned 
> cmd,
>  {
> const struct usb_endpoint_descriptor *desc = dep->endpoint.desc;
> struct dwc3 *dwc = dep->dwc;
> -   u32 timeout = 1000;
> +   u32 timeout = 5000;
> u32 saved_config = 0;
> u32 reg;
>
> --
> 2.15.0-rc2
>


-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH v3 07/12] phy: Add usb phy support for hi3660 Soc of Hisilicon

2019-03-02 Thread Andy Shevchenko
On Sat, Mar 2, 2019 at 11:06 AM Yu Chen  wrote:
>
> This driver handles usb phy power on and shutdown for hi3660 Soc of
> Hisilicon.

Few comments below. After fixing them, FWIW
Reviewed-by: Andy Shevchenko 

> +#define HI3660_USB_DEFAULT_PHY_PARAM   0x1c466e3

A bit of description would be nice to have what this value means.

> +   /* delay for exit from IDDQ mode */
> +   usleep_range(100, 100);

100,100 ? I think you need to give a room to scheduler, at least 20%
margin would be good to have.

> +   /* delay for vbus valid */
> +   usleep_range(100, 100);

Ditto.


-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH v3 10/12] hikey960: Support usb functionality of Hikey960

2019-03-02 Thread Andy Shevchenko
On Sat, Mar 2, 2019 at 11:05 AM Yu Chen  wrote:
>
> This driver handles usb hub power on and typeC port event of HiKey960 board:
> 1)DP&DM switching between usb hub and typeC port base on typeC port
> state
> 2)Control power of usb hub on Hikey960
> 3)Control vbus of typeC port

> +config HISI_HIKEY_USB
> +   tristate "USB functionality of HiSilicon Hikey Platform"
> +   depends on OF && GPIOLIB
> +   help
> + If you say yes here you get support for usb functionality of 
> HiSilicon Hikey Platform.

> +#include 

It's hard to see why this have
depends on OF followed by above header inclusion.

> +   hisi_hikey_usb->typec_vbus = devm_gpiod_get(dev, "typec-vbus",
> +   GPIOD_OUT_LOW);

> +   if (!hisi_hikey_usb->typec_vbus)
> +   return -ENOENT;

Hmm... Is it possible to get NULL pointer from gpiod_get() at all?

> +   if (!hisi_hikey_usb->otg_switch)
> +   return -ENOENT;

Ditto.

> +   /* hub-vdd33-en is optional */
> +   hisi_hikey_usb->hub_vbus = devm_gpiod_get(dev, "hub-vdd33-en",
> +   GPIOD_OUT_HIGH);

devm_gpio_get_optional() if it's indeed optional.

> +   hisi_hikey_usb->role_sw = usb_role_switch_get(dev);
> +   if (!hisi_hikey_usb->role_sw)
> +   return -EPROBE_DEFER;

> +   else if (IS_ERR(hisi_hikey_usb->role_sw))

Redundant 'else'

> +   return PTR_ERR(hisi_hikey_usb->role_sw);

> +static const struct of_device_id id_table_hisi_hikey_usb[] = {
> +   {.compatible = "hisilicon,gpio_hubv1"},
> +   {.compatible = "hisilicon,hikey960_usb"},
> +   {}
> +};

MODULE_DEVICE_TABLE()?

-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH v2 2/2] usb: typec: add typec switch via GPIO control

2019-03-02 Thread Andy Shevchenko
On Fri, Mar 1, 2019 at 3:25 AM Jun Li  wrote:
>
> This patch adds a simple typec switch driver which only needs
> a GPIO to switch the super speed active channel according to
> typec orientation.

FWIW,
Reviewed-by: Andy Shevchenko 

One minor below.

>
> Signed-off-by: Li Jun 
> ---
>
> Changes for v2:
> - Use the correct head files for gpio api and of_device_id:
>   #include 
>   #include 
> - Add driver dependency on GPIOLIB
>
>  drivers/usb/typec/mux/Kconfig   |   7 +++
>  drivers/usb/typec/mux/Makefile  |   1 +
>  drivers/usb/typec/mux/gpio-switch.c | 105 
> 
>  3 files changed, 113 insertions(+)
>
> diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig
> index 01ed0d5..27120e6 100644
> --- a/drivers/usb/typec/mux/Kconfig
> +++ b/drivers/usb/typec/mux/Kconfig
> @@ -9,4 +9,11 @@ config TYPEC_MUX_PI3USB30532
>   Say Y or M if your system has a Pericom PI3USB30532 Type-C cross
>   switch / mux chip found on some devices with a Type-C port.
>
> +config TYPEC_SWITCH_GPIO
> +   tristate "Simple Super Speed Active Switch via GPIO"
> +   depends on GPIOLIB
> +   help
> + Say Y or M if your system has a typec super speed channel
> + switch via a simple GPIO control.
> +
>  endmenu
> diff --git a/drivers/usb/typec/mux/Makefile b/drivers/usb/typec/mux/Makefile
> index 1332e46..e29377c 100644
> --- a/drivers/usb/typec/mux/Makefile
> +++ b/drivers/usb/typec/mux/Makefile
> @@ -1,3 +1,4 @@
>  # SPDX-License-Identifier: GPL-2.0
>
>  obj-$(CONFIG_TYPEC_MUX_PI3USB30532)+= pi3usb30532.o
> +obj-$(CONFIG_TYPEC_SWITCH_GPIO)+= gpio-switch.o
> diff --git a/drivers/usb/typec/mux/gpio-switch.c 
> b/drivers/usb/typec/mux/gpio-switch.c
> new file mode 100644
> index 000..b01844c
> --- /dev/null
> +++ b/drivers/usb/typec/mux/gpio-switch.c
> @@ -0,0 +1,105 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/**

> + * gpio-switch.c - typec switch via a simple GPIO control.

If under any circumstances file will be renamed this become outdated.
So, better not to include file name in the file.

> + *
> + * Copyright 2019 NXP
> + * Author: Jun Li 
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +struct gpio_typec_switch {
> +   struct typec_switch sw;
> +   struct mutex lock;
> +   struct gpio_desc *ss_sel;
> +};
> +
> +static int switch_gpio_set(struct typec_switch *sw,
> +  enum typec_orientation orientation)
> +{
> +   struct gpio_typec_switch *gpio_sw = container_of(sw,
> +   struct gpio_typec_switch, sw);
> +
> +   mutex_lock(&gpio_sw->lock);
> +
> +   switch (orientation) {
> +   case TYPEC_ORIENTATION_NORMAL:
> +   gpiod_set_value_cansleep(gpio_sw->ss_sel, 1);
> +   break;
> +   case TYPEC_ORIENTATION_REVERSE:
> +   gpiod_set_value_cansleep(gpio_sw->ss_sel, 0);
> +   break;
> +   case TYPEC_ORIENTATION_NONE:
> +   break;
> +   }
> +
> +   mutex_unlock(&gpio_sw->lock);
> +
> +   return 0;
> +}
> +
> +static int typec_switch_gpio_probe(struct platform_device *pdev)
> +{
> +   struct gpio_typec_switch*gpio_sw;
> +   struct device   *dev = &pdev->dev;
> +   int ret;
> +
> +   gpio_sw = devm_kzalloc(dev, sizeof(*gpio_sw), GFP_KERNEL);
> +   if (!gpio_sw)
> +   return -ENOMEM;
> +
> +   platform_set_drvdata(pdev, gpio_sw);
> +
> +   gpio_sw->sw.dev = dev;
> +   gpio_sw->sw.set = switch_gpio_set;
> +   mutex_init(&gpio_sw->lock);
> +
> +   /* Get the super speed active channel selection GPIO */
> +   gpio_sw->ss_sel = devm_gpiod_get(dev, NULL, GPIOD_OUT_LOW);
> +   if (IS_ERR(gpio_sw->ss_sel))
> +   return PTR_ERR(gpio_sw->ss_sel);
> +
> +   ret = typec_switch_register(&gpio_sw->sw);
> +   if (ret) {
> +   dev_err(dev, "Error registering typec switch: %d\n", ret);
> +   return ret;
> +   }
> +
> +   return 0;
> +}
> +
> +static int typec_switch_gpio_remove(struct platform_device *pdev)
> +{
> +   struct gpio_typec_switch *gpio_sw = platform_get_drvdata(pdev);
> +
> +   typec_switch_unregister(&gpio_sw->sw);
> +
> +   return 0;
> +}
> +
> +static const struct of_device_id of_typec_switch_gpio_match[] = {
> +   { .compatible = "nxp,ptn36043" },
> +   { /* Sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, of_typec_switch_gpio_match);
> +
> +static struct platform_driver typec_switch_gpio_driver = {
> +   .probe  = typec_switch_gpio_probe,
> +   .remove = typec_switch_gpio_remove,
> +   .driver = {
> +   .name   = "typec-switch-gpio",
> +   .of_match_table = of_typec_switch_gpio_match,
> +   },
> +};
> +
> +module_platform_driver(typec_switch_gpio_drive

[BUG] ASIX AX88179 USB-Ethernet NICs not sending/receiving frames

2019-03-02 Thread Bradley Chapman

All,

I am trying to get an ASIX AX88179 USB 3.0 dual Ethernet NIC dongle to 
work on an SFF system running Linux 4.20.13. The NICs are properly 
detected and named eth3 and eth4 by udev and I can configure and 
administer them like any other NIC, but neither interface is able to 
fully establish a link beat and exchange Ethernet frames with any 
attached device.


I checked to see if the drivers were still maintained and it appears, 
according to https://github.com/FreddyXin/ax88179_178a, that the drivers 
were last maintained in February 2013. As far as I can tell, I've 
selected all the right Kconfig options for my kernel; I do see some 
stuff under CONFIG_GENERIC_PHY and CONFIG_PHYLIB that might be relevant 
but the documentation is inconsistent.


lsusb -v -t:

/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 5000M
|__ Port 2: Dev 2, If 0, Class=hub, Driver=hub/4p, 5000M
|__ Port 1: Dev 3, If 0, Class=vend., Driver=ax88179_178a, 5000M
|__ Port 2: Dev 4, If 0, Class=vend., Driver=ax88179_178a, 5000M

lspci:

04:00.0 USB controller: ASMedia Technology Inc. ASM1042 SuperSpeed USB 
Host Controller


Kconfig:

CONFIG_USB_NET_AX8817X=y
CONFIG_USB_NET_AX88179_178A=y

dmesg snippets:

[0.367286] xhci_hcd :04:00.0: xHCI Host Controller
[0.367289] xhci_hcd :04:00.0: new USB bus registered, assigned 
bus number 3
[0.473915] xhci_hcd :04:00.0: hcc params 0x0200f180 hci version 
0x96 quirks 0x0008

[0.474405] xhci_hcd :04:00.0: xHCI Host Controller
[0.474407] xhci_hcd :04:00.0: new USB bus registered, assigned 
bus number 4

[0.474409] xhci_hcd :04:00.0: Host supports USB 3.0  SuperSpeed
[0.474443] usb usb4: We don't know the algorithms for LPM for this 
host, disabling LPM.

[0.474551] hub 4-0:1.0: USB hub found
[0.474561] hub 4-0:1.0: 2 ports detected
[1.202211] usb 4-2: new SuperSpeed Gen 1 USB device number 2 using 
xhci_hcd

[1.371725] hub 4-2:1.0: USB hub found
[1.371939] hub 4-2:1.0: 4 ports detected
[1.818569] usb 4-2.1: new SuperSpeed Gen 1 USB device number 3 using 
xhci_hcd
[2.525608] ax88179_178a 4-2.1:1.0 eth1: register 'ax88179_178a' at 
usb-:04:00.0-2.1, ASIX AX88179 USB 3.0 Gigabit Ethernet, 
00:0a:cd:2f:24:c9
[2.647403] usb 4-2.2: new SuperSpeed Gen 1 USB device number 4 using 
xhci_hcd
[3.285773] ax88179_178a 4-2.2:1.0 eth3: register 'ax88179_178a' at 
usb-:04:00.0-2.2, ASIX AX88179 USB 3.0 Gigabit Ethernet, 
00:0a:cd:2f:24:c8

[3.294077] ax88179_178a 4-2.2:1.0 eth4: renamed from eth3
[3.310712] ax88179_178a 4-2.1:1.0 eth3: renamed from eth1
[9.887256] ax88179_178a 4-2.1:1.0 eth3: Failed to read reg index 
0x: -110
[   15.007258] ax88179_178a 4-2.1:1.0 eth3: Failed to read reg index 
0x0001: -110
[   20.127228] ax88179_178a 4-2.1:1.0 eth3: Failed to read reg index 
0x0009: -110

[ 1431.076463] IPv6: ADDRCONF(NETDEV_UP): eth3: link is not ready
[ 1436.253354] ax88179_178a 4-2.1:1.0 eth3: Failed to read reg index 
0x: -110
[ 1441.373148] ax88179_178a 4-2.1:1.0 eth3: Failed to read reg index 
0x0001: -110
[ 1446.493014] ax88179_178a 4-2.1:1.0 eth3: Failed to read reg index 
0x0009: -110

[ 1648.735215] ax88179_178a 4-2.1:1.0 eth3: ax88179 - Link status is: 1
[ 1648.742353] IPv6: ADDRCONF(NETDEV_CHANGE): eth3: link becomes ready
[ 1958.264142] ax88179_178a 4-2.1:1.0 eth3: ax88179 - Link status is: 0
[ 1967.224863] ax88179_178a 4-2.1:1.0 eth3: ax88179 - Link status is: 1
[ 1972.293726] ax88179_178a 4-2.1:1.0 eth3: Failed to write reg index 
0x0002: -110

[ 1995.259117] ax88179_178a 4-2.1:1.0 eth3: ax88179 - Link status is: 1
[ 1997.892589] ax88179_178a 4-2.1:1.0 eth3: Failed to read reg index 
0x: -110
[ 2003.012309] ax88179_178a 4-2.1:1.0 eth3: Failed to write reg index 
0x0002: -110
[ 2008.132053] ax88179_178a 4-2.1:1.0 eth3: Failed to write reg index 
0x0002: -110

[ 2032.126090] ax88179_178a 4-2.1:1.0 eth3: ax88179 - Link status is: 1
[ 2171.196246] ax88179_178a 4-2.1:1.0 eth3: Failed to read reg index 
0x0002: -110
[ 2176.315997] ax88179_178a 4-2.1:1.0 eth3: Failed to write reg index 
0x0002: -110

[ 2182.038412] IPv6: ADDRCONF(NETDEV_UP): eth3: link is not ready

The dmesg implies that either the driver or the NICs themselves are not 
able to get a link beat with the connected device (a TP-Link gigabit 
switch).  I tried to interrogate the PHY on each NIC with mii-diag and 
got the following:


Basic registers of MII PHY #3:         .
  No MII transceiver present!.

I checked with ethtool and it returned the following info about each NIC:

ethtool:

Settings for eth3:
Supported ports: [ TP MII ]
Supported link modes:   10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Supported pause frame use: No
Supports auto-negotiation: Yes
Advertised link modes:  Not reported