2019-05-21 12:03:44

by Marek Szyprowski

[permalink] [raw]
Subject: [PATCH 0/5] Exynos EHCI/OHCI: resolve conflict with the generic USB device bindings

Dear All,

Commit 69bec7259853 ("USB: core: let USB device know device node") added
support for attaching devicetree node for USB devices. Those nodes are
children of their USB host controller. However Exynos EHCI and OHCI
driver bindings already define child-nodes for each physical root hub
port and assigns respective PHY controller and parameters to them. This
leads to the conflict. A workaround for it has been merged as commit
01d4071486fe ("usb: exynos: add workaround for the USB device bindings
conflict"), but it disabled support for USB device binding for Exynos
EHCI/OHCI controllers.

This patchset tries to resolve this binding conflict by changing Exynos
EHCI/OHCI bindings: PHYs are moved from the sub-nodes to a standard array
under the 'phys' property. Such solution has been suggested by Måns
Rullgård in the following thread: https://lkml.org/lkml/2019/5/13/228

To keep everything working during the transitional time, the changes has
been split into 2 steps. First step (patches 1-3) need to be merged before
the second one (patches 4-5). Patches from each step can be merged to
respective trees without any dependencies - the only requirement is that
second step has to be merged after merging all patches from the first one.

This patchset has been tested on various Exynos4 boards with different
USB host controller configurations (Odroids family: X2, U3, XU3).

Best regards
Marek Szyprowski
Samsung R&D Institute Poland


Marek Szyprowski (5):
dt-bindings: switch Exynos EHCI/OHCI bindings to use array of generic
PHYs
ARM: dts: exynos: Add array of generic PHYs to EHCI/OHCI devices
usb: exynos: add support for getting PHYs from the standard dt array
ARM: dts: exynos: Remove obsolete port sub-nodes from EHCI/OHCI
devices
usb: exynos: Remove support for legacy PHY bindings

.../devicetree/bindings/usb/exynos-usb.txt | 41 ++++++----------
arch/arm/boot/dts/exynos4.dtsi | 28 ++---------
.../boot/dts/exynos4210-universal_c210.dts | 8 +---
arch/arm/boot/dts/exynos4412-itop-elite.dts | 9 +---
arch/arm/boot/dts/exynos4412-odroidu3.dts | 8 +---
arch/arm/boot/dts/exynos4412-odroidx.dts | 5 +-
arch/arm/boot/dts/exynos4412-origen.dts | 9 +---
arch/arm/boot/dts/exynos5250.dtsi | 16 ++-----
arch/arm/boot/dts/exynos54xx.dtsi | 18 ++-----
drivers/usb/host/ehci-exynos.c | 48 +++----------------
drivers/usb/host/ohci-exynos.c | 48 +++----------------
11 files changed, 50 insertions(+), 188 deletions(-)

--
2.17.1



2019-05-21 12:04:09

by Marek Szyprowski

[permalink] [raw]
Subject: [PATCH 2/5] ARM: dts: exynos: Add array of generic PHYs to EHCI/OHCI devices

Add a standard array of PHYs to Exynos EHCI/OHCI devices. This is a first
step in resolving the conflict between Exynos EHCI/OHCI sub-nodes and
generic USB device bindings. Later the sub-nodes currently used for
assigning PHYs to root ports of the controller will be removed making
a place for the generic USB device bindings nodes.

Suggested-by: Måns Rullgård <[email protected]>
Signed-off-by: Marek Szyprowski <[email protected]>
---
arch/arm/boot/dts/exynos4.dtsi | 4 ++++
arch/arm/boot/dts/exynos4210-universal_c210.dts | 2 ++
arch/arm/boot/dts/exynos4412-itop-elite.dts | 2 ++
arch/arm/boot/dts/exynos4412-odroidu3.dts | 2 ++
arch/arm/boot/dts/exynos4412-odroidx.dts | 2 ++
arch/arm/boot/dts/exynos4412-origen.dts | 2 ++
arch/arm/boot/dts/exynos5250.dtsi | 4 ++++
arch/arm/boot/dts/exynos54xx.dtsi | 4 ++++
8 files changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 36ccf227434d..7b94fbd9ed6c 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -380,6 +380,8 @@
clocks = <&clock CLK_USB_HOST>;
clock-names = "usbhost";
status = "disabled";
+ phys = <&exynos_usbphy 1>, <&exynos_usbphy 2>, <&exynos_usbphy 3>;
+ phy-names = "host", "hsic0", "hsic1";
#address-cells = <1>;
#size-cells = <0>;
port@0 {
@@ -406,6 +408,8 @@
clocks = <&clock CLK_USB_HOST>;
clock-names = "usbhost";
status = "disabled";
+ phys = <&exynos_usbphy 1>;
+ phy-names = "host";
#address-cells = <1>;
#size-cells = <0>;
port@0 {
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index bf092e97e14f..dbd6b43dbe52 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -204,6 +204,8 @@

&ehci {
status = "okay";
+ phys = <&exynos_usbphy 1>;
+ phy-names = "host";
port@0 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/exynos4412-itop-elite.dts b/arch/arm/boot/dts/exynos4412-itop-elite.dts
index 0dedeba89b5f..1763b42c01cb 100644
--- a/arch/arm/boot/dts/exynos4412-itop-elite.dts
+++ b/arch/arm/boot/dts/exynos4412-itop-elite.dts
@@ -146,6 +146,8 @@
/* In order to reset USB ethernet */
samsung,vbus-gpio = <&gpc0 1 GPIO_ACTIVE_HIGH>;

+ phys = <&exynos_usbphy 1>, <&exynos_usbphy 3>;
+ phy-names = "host", "hsic1";
port@0 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/exynos4412-odroidu3.dts b/arch/arm/boot/dts/exynos4412-odroidu3.dts
index 96d99887bceb..5bbaccffc9be 100644
--- a/arch/arm/boot/dts/exynos4412-odroidu3.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidu3.dts
@@ -105,6 +105,8 @@
};

&ehci {
+ phys = <&exynos_usbphy 2>, <&exynos_usbphy 3>;
+ phy-names = "hsic0", "hsic1";
port@1 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts b/arch/arm/boot/dts/exynos4412-odroidx.dts
index a2251581f6b6..306dd9365a91 100644
--- a/arch/arm/boot/dts/exynos4412-odroidx.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidx.dts
@@ -72,6 +72,8 @@
};

&ehci {
+ phys = <&exynos_usbphy 2>;
+ phy-names = "hsic0";
port@1 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
index 698de4345d16..e609e2af22d1 100644
--- a/arch/arm/boot/dts/exynos4412-origen.dts
+++ b/arch/arm/boot/dts/exynos4412-origen.dts
@@ -88,6 +88,8 @@
&ehci {
samsung,vbus-gpio = <&gpx3 5 1>;
status = "okay";
+ phys = <&exynos_usbphy 2>, <&exynos_usbphy 3>;
+ phy-names = "hsic0", "hsic1";

port@1 {
status = "okay";
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index d5e0392b409e..2d23e99985e1 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -617,6 +617,8 @@

clocks = <&clock CLK_USB2>;
clock-names = "usbhost";
+ phys = <&usb2_phy_gen 1>;
+ phy-names = "host";
#address-cells = <1>;
#size-cells = <0>;
port@0 {
@@ -632,6 +634,8 @@

clocks = <&clock CLK_USB2>;
clock-names = "usbhost";
+ phys = <&usb2_phy_gen 1>;
+ phy-names = "host";
#address-cells = <1>;
#size-cells = <0>;
port@0 {
diff --git a/arch/arm/boot/dts/exynos54xx.dtsi b/arch/arm/boot/dts/exynos54xx.dtsi
index ae866bcc30c4..ab1642cf0428 100644
--- a/arch/arm/boot/dts/exynos54xx.dtsi
+++ b/arch/arm/boot/dts/exynos54xx.dtsi
@@ -180,6 +180,8 @@
compatible = "samsung,exynos4210-ehci";
reg = <0x12110000 0x100>;
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy 1>;
+ phy-names = "host";

#address-cells = <1>;
#size-cells = <0>;
@@ -193,6 +195,8 @@
compatible = "samsung,exynos4210-ohci";
reg = <0x12120000 0x100>;
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy 1>;
+ phy-names = "host";

#address-cells = <1>;
#size-cells = <0>;
--
2.17.1


2019-05-21 12:04:48

by Marek Szyprowski

[permalink] [raw]
Subject: [PATCH 1/5] dt-bindings: switch Exynos EHCI/OHCI bindings to use array of generic PHYs

Commit 69bec7259853 ("USB: core: let USB device know device node") added
support for attaching devicetree node for USB devices. Those nodes are
children of their USB host controller. However Exynos EHCI and OHCI
driver bindings already define child-nodes for each physical root hub
port and assigns respective PHY controller and parameters to them. This
leads to the conflict. A workaround for it has been merged as commit
01d4071486fe ("usb: exynos: add workaround for the USB device bindings
conflict"), but it disabled support for USB device binding for Exynos
EHCI/OHCI controllers.

To resolve it properly, lets move PHYs from the sub-nodes to a standard
array under the 'phys' property.

Suggested-by: Måns Rullgård <[email protected]>
Signed-off-by: Marek Szyprowski <[email protected]>
---
.../devicetree/bindings/usb/exynos-usb.txt | 41 +++++++------------
1 file changed, 14 insertions(+), 27 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt
index b7111f43fa59..66c394f9e11f 100644
--- a/Documentation/devicetree/bindings/usb/exynos-usb.txt
+++ b/Documentation/devicetree/bindings/usb/exynos-usb.txt
@@ -12,13 +12,11 @@ Required properties:
- interrupts: interrupt number to the cpu.
- clocks: from common clock binding: handle to usb clock.
- clock-names: from common clock binding: Shall be "usbhost".
- - port: if in the SoC there are EHCI phys, they should be listed here.
- One phy per port. Each port should have following entries:
- - reg: port number on EHCI controller, e.g
- On Exynos5250, port 0 is USB2.0 otg phy
- port 1 is HSIC phy0
- port 2 is HSIC phy1
- - phys: from the *Generic PHY* bindings; specifying phy used by port.
+ - phys: from the *Generic PHY* bindings; array specifying phy(s) used
+ by the root port.
+ - phy-names: from the *Generic PHY* bindings; array of the names for
+ each phy for the root ports, must be a subset of the following:
+ "host", "hsic0", "hsic1".

Optional properties:
- samsung,vbus-gpio: if present, specifies the GPIO that
@@ -35,12 +33,8 @@ Example:
clocks = <&clock 285>;
clock-names = "usbhost";

- #address-cells = <1>;
- #size-cells = <0>;
- port@0 {
- reg = <0>;
- phys = <&usb2phy 1>;
- };
+ phys = <&usb2phy 1>;
+ phy-names = "host";
};

OHCI
@@ -52,13 +46,11 @@ Required properties:
- interrupts: interrupt number to the cpu.
- clocks: from common clock binding: handle to usb clock.
- clock-names: from common clock binding: Shall be "usbhost".
- - port: if in the SoC there are OHCI phys, they should be listed here.
- One phy per port. Each port should have following entries:
- - reg: port number on OHCI controller, e.g
- On Exynos5250, port 0 is USB2.0 otg phy
- port 1 is HSIC phy0
- port 2 is HSIC phy1
- - phys: from the *Generic PHY* bindings, specifying phy used by port.
+ - phys: from the *Generic PHY* bindings; array specifying phy(s) used
+ by the root port.
+ - phy-names: from the *Generic PHY* bindings; array of the names for
+ each phy for the root ports, must be a subset of the following:
+ "host", "hsic0", "hsic1".

Example:
usb@12120000 {
@@ -69,13 +61,8 @@ Example:
clocks = <&clock 285>;
clock-names = "usbhost";

- #address-cells = <1>;
- #size-cells = <0>;
- port@0 {
- reg = <0>;
- phys = <&usb2phy 1>;
- };
-
+ phys = <&usb2phy 1>;
+ phy-names = "host";
};

DWC3
--
2.17.1


2019-05-21 12:05:16

by Marek Szyprowski

[permalink] [raw]
Subject: [PATCH 3/5] usb: exynos: add support for getting PHYs from the standard dt array

Add the code for getting generic PHYs from standard device tree array
from the main controller device node. This is a first step in resolving
the conflict between Exynos EHCI/OHCI sub-nodes and generic USB device
bindings. Later the sub-nodes currently used for assigning PHYs to root
ports of the controller will be removed making a place for the generic
USB device bindings nodes.

Suggested-by: Måns Rullgård <[email protected]>
Signed-off-by: Marek Szyprowski <[email protected]>
---
drivers/usb/host/ehci-exynos.c | 14 +++++++++++++-
drivers/usb/host/ohci-exynos.c | 14 +++++++++++++-
2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index 3a29a1a8519c..2a551a807ec0 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -50,10 +50,22 @@ static int exynos_ehci_get_phy(struct device *dev,
{
struct device_node *child;
struct phy *phy;
- int phy_number;
+ int phy_number, num_phys;
int ret;

/* Get PHYs for the controller */
+ num_phys = of_count_phandle_with_args(dev->of_node, "phys",
+ "#phy-cells");
+ for (phy_number = 0; phy_number < num_phys; phy_number++) {
+ phy = devm_of_phy_get_by_index(dev, dev->of_node, phy_number);
+ if (IS_ERR(phy))
+ return PTR_ERR(phy);
+ exynos_ehci->phy[phy_number] = phy;
+ }
+ if (num_phys)
+ return 0;
+
+ /* Get PHYs using legacy bindings */
for_each_available_child_of_node(dev->of_node, child) {
ret = of_property_read_u32(child, "reg", &phy_number);
if (ret) {
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index 905c6317e0c3..195ea5fa021e 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -39,10 +39,22 @@ static int exynos_ohci_get_phy(struct device *dev,
{
struct device_node *child;
struct phy *phy;
- int phy_number;
+ int phy_number, num_phys;
int ret;

/* Get PHYs for the controller */
+ num_phys = of_count_phandle_with_args(dev->of_node, "phys",
+ "#phy-cells");
+ for (phy_number = 0; phy_number < num_phys; phy_number++) {
+ phy = devm_of_phy_get_by_index(dev, dev->of_node, phy_number);
+ if (IS_ERR(phy))
+ return PTR_ERR(phy);
+ exynos_ohci->phy[phy_number] = phy;
+ }
+ if (num_phys)
+ return 0;
+
+ /* Get PHYs using legacy bindings */
for_each_available_child_of_node(dev->of_node, child) {
ret = of_property_read_u32(child, "reg", &phy_number);
if (ret) {
--
2.17.1


2019-05-21 12:06:52

by Marek Szyprowski

[permalink] [raw]
Subject: [PATCH 4/5] ARM: dts: exynos: Remove obsolete port sub-nodes from EHCI/OHCI devices

Remove custom port sub-nodes from EHCI/OHCI devices. This way boards can
define sub-nodes for the USB devices using generic USB device bindings.

Suggested-by: Måns Rullgård <[email protected]>
Signed-off-by: Marek Szyprowski <[email protected]>
---
arch/arm/boot/dts/exynos4.dtsi | 24 -------------------
.../boot/dts/exynos4210-universal_c210.dts | 6 -----
arch/arm/boot/dts/exynos4412-itop-elite.dts | 7 ------
arch/arm/boot/dts/exynos4412-odroidu3.dts | 6 -----
arch/arm/boot/dts/exynos4412-odroidx.dts | 3 ---
arch/arm/boot/dts/exynos4412-origen.dts | 7 ------
arch/arm/boot/dts/exynos5250.dtsi | 12 ----------
arch/arm/boot/dts/exynos54xx.dtsi | 14 -----------
8 files changed, 79 deletions(-)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 7b94fbd9ed6c..09cae6a0ca77 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -382,23 +382,6 @@
status = "disabled";
phys = <&exynos_usbphy 1>, <&exynos_usbphy 2>, <&exynos_usbphy 3>;
phy-names = "host", "hsic0", "hsic1";
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 {
- reg = <0>;
- phys = <&exynos_usbphy 1>;
- status = "disabled";
- };
- port@1 {
- reg = <1>;
- phys = <&exynos_usbphy 2>;
- status = "disabled";
- };
- port@2 {
- reg = <2>;
- phys = <&exynos_usbphy 3>;
- status = "disabled";
- };
};

ohci: ohci@12590000 {
@@ -410,13 +393,6 @@
status = "disabled";
phys = <&exynos_usbphy 1>;
phy-names = "host";
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 {
- reg = <0>;
- phys = <&exynos_usbphy 1>;
- status = "disabled";
- };
};

i2s1: i2s@13960000 {
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index dbd6b43dbe52..c1c2fd537333 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -206,9 +206,6 @@
status = "okay";
phys = <&exynos_usbphy 1>;
phy-names = "host";
- port@0 {
- status = "okay";
- };
};

&exynos_usbphy {
@@ -517,9 +514,6 @@

&ohci {
status = "okay";
- port@0 {
- status = "okay";
- };
};

&pinctrl_1 {
diff --git a/arch/arm/boot/dts/exynos4412-itop-elite.dts b/arch/arm/boot/dts/exynos4412-itop-elite.dts
index 1763b42c01cb..f6d0a5f5d339 100644
--- a/arch/arm/boot/dts/exynos4412-itop-elite.dts
+++ b/arch/arm/boot/dts/exynos4412-itop-elite.dts
@@ -148,13 +148,6 @@

phys = <&exynos_usbphy 1>, <&exynos_usbphy 3>;
phy-names = "host", "hsic1";
- port@0 {
- status = "okay";
- };
-
- port@2 {
- status = "okay";
- };
};

&exynos_usbphy {
diff --git a/arch/arm/boot/dts/exynos4412-odroidu3.dts b/arch/arm/boot/dts/exynos4412-odroidu3.dts
index 5bbaccffc9be..8ff243ba4542 100644
--- a/arch/arm/boot/dts/exynos4412-odroidu3.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidu3.dts
@@ -107,12 +107,6 @@
&ehci {
phys = <&exynos_usbphy 2>, <&exynos_usbphy 3>;
phy-names = "hsic0", "hsic1";
- port@1 {
- status = "okay";
- };
- port@2 {
- status = "okay";
- };
};

&sound {
diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts b/arch/arm/boot/dts/exynos4412-odroidx.dts
index 306dd9365a91..3ea2a0101e80 100644
--- a/arch/arm/boot/dts/exynos4412-odroidx.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidx.dts
@@ -74,9 +74,6 @@
&ehci {
phys = <&exynos_usbphy 2>;
phy-names = "hsic0";
- port@1 {
- status = "okay";
- };
};

&mshc_0 {
diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
index e609e2af22d1..ecd14b283a6b 100644
--- a/arch/arm/boot/dts/exynos4412-origen.dts
+++ b/arch/arm/boot/dts/exynos4412-origen.dts
@@ -90,13 +90,6 @@
status = "okay";
phys = <&exynos_usbphy 2>, <&exynos_usbphy 3>;
phy-names = "hsic0", "hsic1";
-
- port@1 {
- status = "okay";
- };
- port@2 {
- status = "okay";
- };
};

&fimd {
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 2d23e99985e1..c5584f40ebfb 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -619,12 +619,6 @@
clock-names = "usbhost";
phys = <&usb2_phy_gen 1>;
phy-names = "host";
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 {
- reg = <0>;
- phys = <&usb2_phy_gen 1>;
- };
};

ohci: usb@12120000 {
@@ -636,12 +630,6 @@
clock-names = "usbhost";
phys = <&usb2_phy_gen 1>;
phy-names = "host";
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 {
- reg = <0>;
- phys = <&usb2_phy_gen 1>;
- };
};

usb2_phy_gen: phy@12130000 {
diff --git a/arch/arm/boot/dts/exynos54xx.dtsi b/arch/arm/boot/dts/exynos54xx.dtsi
index ab1642cf0428..97746a68791a 100644
--- a/arch/arm/boot/dts/exynos54xx.dtsi
+++ b/arch/arm/boot/dts/exynos54xx.dtsi
@@ -182,13 +182,6 @@
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
phys = <&usb2_phy 1>;
phy-names = "host";
-
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 {
- reg = <0>;
- phys = <&usb2_phy 1>;
- };
};

usbhost1: usb@12120000 {
@@ -197,13 +190,6 @@
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
phys = <&usb2_phy 1>;
phy-names = "host";
-
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 {
- reg = <0>;
- phys = <&usb2_phy 1>;
- };
};

usb2_phy: phy@12130000 {
--
2.17.1


2019-05-21 12:07:10

by Marek Szyprowski

[permalink] [raw]
Subject: [PATCH 5/5] usb: exynos: Remove support for legacy PHY bindings

Exnyos EHCI/OHCI custom port device tree sub-nodes under EHCI/OHCI
devices has been removed, so the code for handling them can be also
removed. Once this has been done, we can also remove the workaround
added by commit 01d4071486fe ("usb: exynos: add workaround for the USB
device bindings conflict") and enable support for the generic USB device
bindings.

Suggested-by: Måns Rullgård <[email protected]>
Signed-off-by: Marek Szyprowski <[email protected]>
---
drivers/usb/host/ehci-exynos.c | 46 ----------------------------------
drivers/usb/host/ohci-exynos.c | 46 ----------------------------------
2 files changed, 92 deletions(-)

diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index 2a551a807ec0..afde1ffa0824 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -39,7 +39,6 @@ static struct hc_driver __read_mostly exynos_ehci_hc_driver;

struct exynos_ehci_hcd {
struct clk *clk;
- struct device_node *of_node;
struct phy *phy[PHY_NUMBER];
};

@@ -48,10 +47,8 @@ struct exynos_ehci_hcd {
static int exynos_ehci_get_phy(struct device *dev,
struct exynos_ehci_hcd *exynos_ehci)
{
- struct device_node *child;
struct phy *phy;
int phy_number, num_phys;
- int ret;

/* Get PHYs for the controller */
num_phys = of_count_phandle_with_args(dev->of_node, "phys",
@@ -62,39 +59,6 @@ static int exynos_ehci_get_phy(struct device *dev,
return PTR_ERR(phy);
exynos_ehci->phy[phy_number] = phy;
}
- if (num_phys)
- return 0;
-
- /* Get PHYs using legacy bindings */
- for_each_available_child_of_node(dev->of_node, child) {
- ret = of_property_read_u32(child, "reg", &phy_number);
- if (ret) {
- dev_err(dev, "Failed to parse device tree\n");
- of_node_put(child);
- return ret;
- }
-
- if (phy_number >= PHY_NUMBER) {
- dev_err(dev, "Invalid number of PHYs\n");
- of_node_put(child);
- return -EINVAL;
- }
-
- phy = devm_of_phy_get(dev, child, NULL);
- exynos_ehci->phy[phy_number] = phy;
- if (IS_ERR(phy)) {
- ret = PTR_ERR(phy);
- if (ret == -EPROBE_DEFER) {
- of_node_put(child);
- return ret;
- } else if (ret != -ENOSYS && ret != -ENODEV) {
- dev_err(dev,
- "Error retrieving usb2 phy: %d\n", ret);
- of_node_put(child);
- return ret;
- }
- }
- }

return 0;
}
@@ -216,13 +180,6 @@ static int exynos_ehci_probe(struct platform_device *pdev)
ehci = hcd_to_ehci(hcd);
ehci->caps = hcd->regs;

- /*
- * Workaround: reset of_node pointer to avoid conflict between Exynos
- * EHCI port subnodes and generic USB device bindings
- */
- exynos_ehci->of_node = pdev->dev.of_node;
- pdev->dev.of_node = NULL;
-
/* DMA burst Enable */
writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));

@@ -239,7 +196,6 @@ static int exynos_ehci_probe(struct platform_device *pdev)

fail_add_hcd:
exynos_ehci_phy_disable(&pdev->dev);
- pdev->dev.of_node = exynos_ehci->of_node;
fail_io:
clk_disable_unprepare(exynos_ehci->clk);
fail_clk:
@@ -252,8 +208,6 @@ static int exynos_ehci_remove(struct platform_device *pdev)
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);

- pdev->dev.of_node = exynos_ehci->of_node;
-
usb_remove_hcd(hcd);

exynos_ehci_phy_disable(&pdev->dev);
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index 195ea5fa021e..8e9f4ef4e397 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -30,17 +30,14 @@ static struct hc_driver __read_mostly exynos_ohci_hc_driver;

struct exynos_ohci_hcd {
struct clk *clk;
- struct device_node *of_node;
struct phy *phy[PHY_NUMBER];
};

static int exynos_ohci_get_phy(struct device *dev,
struct exynos_ohci_hcd *exynos_ohci)
{
- struct device_node *child;
struct phy *phy;
int phy_number, num_phys;
- int ret;

/* Get PHYs for the controller */
num_phys = of_count_phandle_with_args(dev->of_node, "phys",
@@ -51,39 +48,6 @@ static int exynos_ohci_get_phy(struct device *dev,
return PTR_ERR(phy);
exynos_ohci->phy[phy_number] = phy;
}
- if (num_phys)
- return 0;
-
- /* Get PHYs using legacy bindings */
- for_each_available_child_of_node(dev->of_node, child) {
- ret = of_property_read_u32(child, "reg", &phy_number);
- if (ret) {
- dev_err(dev, "Failed to parse device tree\n");
- of_node_put(child);
- return ret;
- }
-
- if (phy_number >= PHY_NUMBER) {
- dev_err(dev, "Invalid number of PHYs\n");
- of_node_put(child);
- return -EINVAL;
- }
-
- phy = devm_of_phy_get(dev, child, NULL);
- exynos_ohci->phy[phy_number] = phy;
- if (IS_ERR(phy)) {
- ret = PTR_ERR(phy);
- if (ret == -EPROBE_DEFER) {
- of_node_put(child);
- return ret;
- } else if (ret != -ENOSYS && ret != -ENODEV) {
- dev_err(dev,
- "Error retrieving usb2 phy: %d\n", ret);
- of_node_put(child);
- return ret;
- }
- }
- }

return 0;
}
@@ -183,13 +147,6 @@ static int exynos_ohci_probe(struct platform_device *pdev)
goto fail_io;
}

- /*
- * Workaround: reset of_node pointer to avoid conflict between Exynos
- * OHCI port subnodes and generic USB device bindings
- */
- exynos_ohci->of_node = pdev->dev.of_node;
- pdev->dev.of_node = NULL;
-
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (err) {
dev_err(&pdev->dev, "Failed to add USB HCD\n");
@@ -200,7 +157,6 @@ static int exynos_ohci_probe(struct platform_device *pdev)

fail_add_hcd:
exynos_ohci_phy_disable(&pdev->dev);
- pdev->dev.of_node = exynos_ohci->of_node;
fail_io:
clk_disable_unprepare(exynos_ohci->clk);
fail_clk:
@@ -213,8 +169,6 @@ static int exynos_ohci_remove(struct platform_device *pdev)
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);

- pdev->dev.of_node = exynos_ohci->of_node;
-
usb_remove_hcd(hcd);

exynos_ohci_phy_disable(&pdev->dev);
--
2.17.1


2019-05-21 13:32:47

by Måns Rullgård

[permalink] [raw]
Subject: Re: [PATCH 0/5] Exynos EHCI/OHCI: resolve conflict with the generic USB device bindings

Marek Szyprowski <[email protected]> writes:

> Dear All,
>
> Commit 69bec7259853 ("USB: core: let USB device know device node") added
> support for attaching devicetree node for USB devices. Those nodes are
> children of their USB host controller. However Exynos EHCI and OHCI
> driver bindings already define child-nodes for each physical root hub
> port and assigns respective PHY controller and parameters to them. This
> leads to the conflict. A workaround for it has been merged as commit
> 01d4071486fe ("usb: exynos: add workaround for the USB device bindings
> conflict"), but it disabled support for USB device binding for Exynos
> EHCI/OHCI controllers.
>
> This patchset tries to resolve this binding conflict by changing Exynos
> EHCI/OHCI bindings: PHYs are moved from the sub-nodes to a standard array
> under the 'phys' property. Such solution has been suggested by M?ns
> Rullg?rd in the following thread: https://lkml.org/lkml/2019/5/13/228
>
> To keep everything working during the transitional time, the changes has
> been split into 2 steps. First step (patches 1-3) need to be merged before
> the second one (patches 4-5). Patches from each step can be merged to
> respective trees without any dependencies - the only requirement is that
> second step has to be merged after merging all patches from the first one.
>
> This patchset has been tested on various Exynos4 boards with different
> USB host controller configurations (Odroids family: X2, U3, XU3).
>
> Best regards
> Marek Szyprowski
> Samsung R&D Institute Poland
>
> Marek Szyprowski (5):
> dt-bindings: switch Exynos EHCI/OHCI bindings to use array of generic
> PHYs
> ARM: dts: exynos: Add array of generic PHYs to EHCI/OHCI devices
> usb: exynos: add support for getting PHYs from the standard dt array
> ARM: dts: exynos: Remove obsolete port sub-nodes from EHCI/OHCI
> devices
> usb: exynos: Remove support for legacy PHY bindings

You could retain compatibility with old devicetrees (which may be
useful) by using the "phys" property if it exists and falling back
on the old method if it doesn't. Then you would get this sequence
of changes:

1. Update binding definition.
2. Support new binding in driver, with fallback to old.
3. Switch dts files to new binding.

--
M?ns Rullg?rd

2019-05-22 06:03:15

by Marek Szyprowski

[permalink] [raw]
Subject: Re: [PATCH 0/5] Exynos EHCI/OHCI: resolve conflict with the generic USB device bindings

Hi Måns

On 2019-05-21 15:30, Måns Rullgård wrote:
> Marek Szyprowski <[email protected]> writes:
>> Dear All,
>>
>> Commit 69bec7259853 ("USB: core: let USB device know device node") added
>> support for attaching devicetree node for USB devices. Those nodes are
>> children of their USB host controller. However Exynos EHCI and OHCI
>> driver bindings already define child-nodes for each physical root hub
>> port and assigns respective PHY controller and parameters to them. This
>> leads to the conflict. A workaround for it has been merged as commit
>> 01d4071486fe ("usb: exynos: add workaround for the USB device bindings
>> conflict"), but it disabled support for USB device binding for Exynos
>> EHCI/OHCI controllers.
>>
>> This patchset tries to resolve this binding conflict by changing Exynos
>> EHCI/OHCI bindings: PHYs are moved from the sub-nodes to a standard array
>> under the 'phys' property. Such solution has been suggested by Måns
>> Rullgård in the following thread: https://lkml.org/lkml/2019/5/13/228
>>
>> To keep everything working during the transitional time, the changes has
>> been split into 2 steps. First step (patches 1-3) need to be merged before
>> the second one (patches 4-5). Patches from each step can be merged to
>> respective trees without any dependencies - the only requirement is that
>> second step has to be merged after merging all patches from the first one.
>>
>> This patchset has been tested on various Exynos4 boards with different
>> USB host controller configurations (Odroids family: X2, U3, XU3).
>>
>> Best regards
>> Marek Szyprowski
>> Samsung R&D Institute Poland
>>
>> Marek Szyprowski (5):
>> dt-bindings: switch Exynos EHCI/OHCI bindings to use array of generic
>> PHYs
>> ARM: dts: exynos: Add array of generic PHYs to EHCI/OHCI devices
>> usb: exynos: add support for getting PHYs from the standard dt array
>> ARM: dts: exynos: Remove obsolete port sub-nodes from EHCI/OHCI
>> devices
>> usb: exynos: Remove support for legacy PHY bindings
> You could retain compatibility with old devicetrees (which may be
> useful) by using the "phys" property if it exists and falling back
> on the old method if it doesn't. Then you would get this sequence
> of changes:
>
> 1. Update binding definition.
> 2. Support new binding in driver, with fallback to old.
> 3. Switch dts files to new binding.

This is exactly what I did in this patchset. Until Patch #5 is applied,
Exynos EHCI/OHCI drivers supports both ways of getting PHYs and is fully
compatible with existing DTBs. This last patch should be applied at
least one release later that the first 3 patches to keep everything
working during the -rcX time.

Compatibility with so called old DTBs is not so important, because there
are no boards with Exynos4 and Exynos5 SoCs, which would not update DTB
together with the kernel zImage. There have been already some
significant compatibility breaks related to those SoCs during last years.


Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland

2019-05-22 10:57:06

by Måns Rullgård

[permalink] [raw]
Subject: Re: [PATCH 0/5] Exynos EHCI/OHCI: resolve conflict with the generic USB device bindings

Marek Szyprowski <[email protected]> writes:

> Hi M?ns
>
> On 2019-05-21 15:30, M?ns Rullg?rd wrote:
>> Marek Szyprowski <[email protected]> writes:
>>> Dear All,
>>>
>>> Commit 69bec7259853 ("USB: core: let USB device know device node") added
>>> support for attaching devicetree node for USB devices. Those nodes are
>>> children of their USB host controller. However Exynos EHCI and OHCI
>>> driver bindings already define child-nodes for each physical root hub
>>> port and assigns respective PHY controller and parameters to them. This
>>> leads to the conflict. A workaround for it has been merged as commit
>>> 01d4071486fe ("usb: exynos: add workaround for the USB device bindings
>>> conflict"), but it disabled support for USB device binding for Exynos
>>> EHCI/OHCI controllers.
>>>
>>> This patchset tries to resolve this binding conflict by changing Exynos
>>> EHCI/OHCI bindings: PHYs are moved from the sub-nodes to a standard array
>>> under the 'phys' property. Such solution has been suggested by M?ns
>>> Rullg?rd in the following thread: https://lkml.org/lkml/2019/5/13/228
>>>
>>> To keep everything working during the transitional time, the changes has
>>> been split into 2 steps. First step (patches 1-3) need to be merged before
>>> the second one (patches 4-5). Patches from each step can be merged to
>>> respective trees without any dependencies - the only requirement is that
>>> second step has to be merged after merging all patches from the first one.
>>>
>>> This patchset has been tested on various Exynos4 boards with different
>>> USB host controller configurations (Odroids family: X2, U3, XU3).
>>>
>>> Best regards
>>> Marek Szyprowski
>>> Samsung R&D Institute Poland
>>>
>>> Marek Szyprowski (5):
>>> dt-bindings: switch Exynos EHCI/OHCI bindings to use array of generic
>>> PHYs
>>> ARM: dts: exynos: Add array of generic PHYs to EHCI/OHCI devices
>>> usb: exynos: add support for getting PHYs from the standard dt array
>>> ARM: dts: exynos: Remove obsolete port sub-nodes from EHCI/OHCI
>>> devices
>>> usb: exynos: Remove support for legacy PHY bindings
>> You could retain compatibility with old devicetrees (which may be
>> useful) by using the "phys" property if it exists and falling back
>> on the old method if it doesn't. Then you would get this sequence
>> of changes:
>>
>> 1. Update binding definition.
>> 2. Support new binding in driver, with fallback to old.
>> 3. Switch dts files to new binding.
>
> This is exactly what I did in this patchset. Until Patch #5 is applied,
> Exynos EHCI/OHCI drivers supports both ways of getting PHYs and is fully
> compatible with existing DTBs. This last patch should be applied at
> least one release later that the first 3 patches to keep everything
> working during the -rcX time.

I'm suggesting you keep the fallback in the driver. It does no harm,
and it's contained in one place.

On the dts side, you're adding the new phys property without removing
the old-style nodes at first. If you put the driver change first, the
dts could be switched to the new style in one patch without a confusing
hybrid ever existing.

> Compatibility with so called old DTBs is not so important, because there
> are no boards with Exynos4 and Exynos5 SoCs, which would not update DTB
> together with the kernel zImage. There have been already some
> significant compatibility breaks related to those SoCs during last years.

You can't possibly know what's out there. Besides, isn't the general
policy to not break compatibility without a very good reason?

--
M?ns Rullg?rd

2019-06-05 08:38:55

by Marek Szyprowski

[permalink] [raw]
Subject: Re: [PATCH 0/5] Exynos EHCI/OHCI: resolve conflict with the generic USB device bindings

Hi Måns,

On 2019-05-22 12:54, Måns Rullgård wrote:
> Marek Szyprowski <[email protected]> writes:
>> On 2019-05-21 15:30, Måns Rullgård wrote:
>>> Marek Szyprowski <[email protected]> writes:
>>>> Commit 69bec7259853 ("USB: core: let USB device know device node") added
>>>> support for attaching devicetree node for USB devices. Those nodes are
>>>> children of their USB host controller. However Exynos EHCI and OHCI
>>>> driver bindings already define child-nodes for each physical root hub
>>>> port and assigns respective PHY controller and parameters to them. This
>>>> leads to the conflict. A workaround for it has been merged as commit
>>>> 01d4071486fe ("usb: exynos: add workaround for the USB device bindings
>>>> conflict"), but it disabled support for USB device binding for Exynos
>>>> EHCI/OHCI controllers.
>>>>
>>>> This patchset tries to resolve this binding conflict by changing Exynos
>>>> EHCI/OHCI bindings: PHYs are moved from the sub-nodes to a standard array
>>>> under the 'phys' property. Such solution has been suggested by Måns
>>>> Rullgård in the following thread: https://lkml.org/lkml/2019/5/13/228
>>>>
>>>> To keep everything working during the transitional time, the changes has
>>>> been split into 2 steps. First step (patches 1-3) need to be merged before
>>>> the second one (patches 4-5). Patches from each step can be merged to
>>>> respective trees without any dependencies - the only requirement is that
>>>> second step has to be merged after merging all patches from the first one.
>>>>
>>>> This patchset has been tested on various Exynos4 boards with different
>>>> USB host controller configurations (Odroids family: X2, U3, XU3).
>>>>
>>>> Best regards
>>>> Marek Szyprowski
>>>> Samsung R&D Institute Poland
>>>>
>>>> Marek Szyprowski (5):
>>>> dt-bindings: switch Exynos EHCI/OHCI bindings to use array of generic
>>>> PHYs
>>>> ARM: dts: exynos: Add array of generic PHYs to EHCI/OHCI devices
>>>> usb: exynos: add support for getting PHYs from the standard dt array
>>>> ARM: dts: exynos: Remove obsolete port sub-nodes from EHCI/OHCI
>>>> devices
>>>> usb: exynos: Remove support for legacy PHY bindings
>>> You could retain compatibility with old devicetrees (which may be
>>> useful) by using the "phys" property if it exists and falling back
>>> on the old method if it doesn't. Then you would get this sequence
>>> of changes:
>>>
>>> 1. Update binding definition.
>>> 2. Support new binding in driver, with fallback to old.
>>> 3. Switch dts files to new binding.
>> This is exactly what I did in this patchset. Until Patch #5 is applied,
>> Exynos EHCI/OHCI drivers supports both ways of getting PHYs and is fully
>> compatible with existing DTBs. This last patch should be applied at
>> least one release later that the first 3 patches to keep everything
>> working during the -rcX time.
> I'm suggesting you keep the fallback in the driver. It does no harm,
> and it's contained in one place.
>
> On the dts side, you're adding the new phys property without removing
> the old-style nodes at first. If you put the driver change first, the
> dts could be switched to the new style in one patch without a confusing
> hybrid ever existing.

This was just a proposed way of applying the patches. We can change the
order and apply patch #3 first, then in the next kernel release, apply
patch #2 and #4 together, and the last step, 2 releases later, apply the
last one. In my proposed approach (apply #2 and #3 together to the
respective kernel trees for the next release), the final result is
applied a release earlier.

>> Compatibility with so called old DTBs is not so important, because there
>> are no boards with Exynos4 and Exynos5 SoCs, which would not update DTB
>> together with the kernel zImage. There have been already some
>> significant compatibility breaks related to those SoCs during last years.
> You can't possibly know what's out there. Besides, isn't the general
> policy to not break compatibility without a very good reason?

There have been already some significant changes and compatibility
breaks in Exynos DTB ABI and noone complained. We can also ignore
completely this patchset and keep compatibility with old DTBs just with
the workaround merged in commit 01d4071486fe18ec91f78725d81c7e46557c629a
("usb: exynos: add workaround for the USB device bindings conflict")...

Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland

2019-06-14 16:32:32

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH 1/5] dt-bindings: switch Exynos EHCI/OHCI bindings to use array of generic PHYs

On Tue, May 21, 2019 at 01:58:45PM +0200, Marek Szyprowski wrote:
> Commit 69bec7259853 ("USB: core: let USB device know device node") added
> support for attaching devicetree node for USB devices. Those nodes are
> children of their USB host controller. However Exynos EHCI and OHCI
> driver bindings already define child-nodes for each physical root hub
> port and assigns respective PHY controller and parameters to them. This
> leads to the conflict. A workaround for it has been merged as commit
> 01d4071486fe ("usb: exynos: add workaround for the USB device bindings
> conflict"), but it disabled support for USB device binding for Exynos
> EHCI/OHCI controllers.
>
> To resolve it properly, lets move PHYs from the sub-nodes to a standard
> array under the 'phys' property.
>
> Suggested-by: M?ns Rullg?rd <[email protected]>
> Signed-off-by: Marek Szyprowski <[email protected]>
> ---
> .../devicetree/bindings/usb/exynos-usb.txt | 41 +++++++------------
> 1 file changed, 14 insertions(+), 27 deletions(-)

Reviewed-by: Rob Herring <[email protected]>

The old way would also conflict with the usb-connector binding as that
uses the graph binding.

Rob