All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 0/9] usb: ehci-vf: make the USB host port usable
@ 2026-10-20 10:15 Mehmet Fide
  2026-10-20 10:16 ` [PATCH v7 1/9] fdtdec: match an alias to its stem only when the number follows it Mehmet Fide
                   ` (8 more replies)
  0 siblings, 9 replies; 21+ messages in thread
From: Mehmet Fide @ 2026-10-20 10:15 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

From: Mehmet Fide <mehmet.fide@screeningeagle.com>

"usb start" on a Colibri VF50 or VF61 kills U-Boot with a data abort,
and even with that fixed the host port stays unpowered:

- patch 1 makes the flat-tree alias lookups match a stem exactly, as
  the live tree does; their prefix match is what gave the two USB
  controllers of the Vybrid the sequence numbers 2 and 3
- patch 2 fixes the data abort: the controller index came from that
  sequence number and indexed past the driver's tables
- patches 3 to 8 drop the dead non-DM path and the empty bind hook,
  add ofnode_get_alias_seq(), take dr_mode through usb_get_dr_mode()
  and the ID detect gpio through the device, and the PHY, usbmisc and
  anatop bases from the device tree instead of the tables
- patch 9 enables the vbus-supply of the port

Patches 3 to 8 are the follow-up Marek asked for in his review of the
data abort fix: the PHY and usbmisc tables are gone, and the port index
that is left, for board_ehci_hcd_init() and the anatop registers, comes
from the usbphy alias of the PHY node.

v7:
- Marek's review of v6: the dr_mode patch is split in two, patch 6 only
  replaces the private enum and the strcmp() chain, the new patch 7
  moves the ID detect gpio request to the device and into the probe,
  checks the results of gpio_request_by_name() and dm_gpio_get_value(),
  and frees the gpio in a new remove hook and on the failing probe
  paths, so the probe that follows a "usb stop" can request it again
- a dr_mode value the driver does not know fails the probe with
  -EINVAL again, as it did before the series; v6 made it host
- patch 8 keeps the u32 portnr, the alias lookup writes a local int
- the tags sit above the Signed-off-by; patch 3 carries Marek's
  Reviewed-by
- Simon's Reviewed-by on v6 carried to patches 1 to 5, whose code is
  unchanged; patches 6 and 8 changed after his review and patch 7 is
  new
- patch 9 drops the Reviewed-by of Marek and Simon on v6: its VBUS code
  is unchanged, but it now adds its line to the remove hook of patch 7
- rebased on main

v6:
- Marek's review of v5: patch 3 names USB_HOST as the option that
  selects DM_USB, patch 4 loses its two Fixes tags, patches 2 and 4
  carry his Reviewed-by
- new patch 6: the driver's own dr_mode enum and parsing go, it uses
  usb_get_dr_mode() and USB_DR_MODE_* as ehci-mx6 does
- patch 7 reads the phandles of the controller node with
  dev_read_phandle_with_args() and passes the private data to the
  helpers instead of single addresses
- patch 8 reports through dev_err() and dev_dbg()

v5:
- Simon's review of patch 4 (now 5): the live and the flat lookup
  treated the stem differently, exact against prefix, and the register
  base patch relied on the prefix to find usbphy0 with the "usb" stem.
  New patch 1 makes the flat lookup exact, ofnode_get_alias_seq()
  documents it and its test checks a prefix stem; the PHY node is
  looked up with the "usbphy" stem
- ofnode_get_alias_seq() now works on a node of any tree, on the live
  tree as well: of_alias_get_id() looks a node outside the control tree
  up in the /aliases node of its own tree; a test uses the other tree of
  the sandbox tests
- the checkpatch note of patch 4 (now 5) moved below the --- line
- rebased on main after the v2026.10 release

v4:
- rebased on next; the dm core change that moved of_to_plat() after
  pinctrl is gone, the regulator GPIO is now claimed at probe time
  upstream, which is what the vbus patch needed
- the data abort fix joins the series, the register base patch depends
  on it
- the vbus patch enables VBUS in the reset hook only, as ehci-mx6 does;
  v3 enabled it there and in the shared init, so the regulator counted
  two enables per probe and "usb stop" never switched VBUS off
- the dm core patch gains a test and no longer documents -ENOENT for a
  missing alias, the live tree returns -ENODEV

v6 of this series:
https://lore.kernel.org/u-boot/20261016072526.2277530-1-mehmet.fide@gmail.com/
v5 of this series:
https://lore.kernel.org/u-boot/20261013090738.377537-1-mehmet.fide@gmail.com/
v4 of this series:
https://lore.kernel.org/u-boot/cover.1791381507.git.mehmet.fide@screeningeagle.com/
v2 of the register base series:
https://lore.kernel.org/u-boot/20260820071511.1036506-1-mehmet.fide@gmail.com/
v3 of the vbus series:
https://lore.kernel.org/u-boot/20260820102523.1076815-1-mehmet.fide@gmail.com/
the data abort fix on its own:
https://lore.kernel.org/u-boot/20260818151236.2891878-1-mehmet.fide@gmail.com/

Tested on a Colibri VF50 V1.2A on the Iris carrier, colibri_vf_defconfig
on main (8d534cec0cc): "usb start" finds a USB stick behind the host
port at usb@400b4000 and reads the same data before and after "usb
reset", VBUS goes on at "usb start" and off at "usb stop", also after
repeated resets, and Linux takes the port over when U-Boot boots it
without "usb stop". The code of patches 1 to 5 is the one tested on a
VF61 V1.2B for v6; patches 6 to 9 changed only in the driver and were
tested on the VF50 as above. With local device trees that make usb0 an
OTG port with the fsl,cdet-gpio colibri_vf had before its device tree
sync, both ID states went through "usb start", "usb reset" and "usb
stop" cycles: read as device, the port is not available on every start
and the gpio stays free; read as host (GPIO_ACTIVE_LOW), the port holds
the gpio while it runs and gives it back at "usb stop". Without the
frees, every probe after the first fails with -EBUSY. An unknown dr_mode
fails the probe with -EINVAL, a missing one gives a host port. The five
ARCH_VF610 boards build at every patch, and "ut dm" on sandbox gives the
same result as on main, plus the three tests of patches 1 and 5 on the
live and the flat tree.

Mehmet Fide (9):
  fdtdec: match an alias to its stem only when the number follows it
  usb: ehci-vf: take the controller index from the device tree
  usb: ehci-vf: remove the code path for a build without DM_USB
  usb: ehci-vf: drop the empty bind hook
  dm: core: add ofnode_get_alias_seq()
  usb: ehci-vf: use usb_get_dr_mode()
  usb: ehci-vf: request the ID detect gpio through the device
  usb: ehci-vf: take the register bases from the device tree
  usb: ehci-vf: enable the vbus supply of the port

 arch/sandbox/dts/other.dts |   5 +
 drivers/core/of_access.c   |  42 ++++++
 drivers/core/ofnode.c      |  20 +++
 drivers/core/read.c        |  20 +--
 drivers/usb/host/ehci-vf.c | 288 ++++++++++++++++++-------------------
 include/dm/of_access.h     |   7 +-
 include/dm/ofnode.h        |  16 +++
 include/dm/read.h          |   8 +-
 lib/fdtdec.c               |  43 ++++--
 test/dm/fdtdec.c           |  35 +++++
 test/dm/ofnode.c           |  49 +++++++
 11 files changed, 348 insertions(+), 185 deletions(-)


base-commit: 8d534cec0cc0109a37c0ded8854da03f1526dc0e
-- 
2.55.0


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v7 1/9] fdtdec: match an alias to its stem only when the number follows it
  2026-10-20 10:15 [PATCH v7 0/9] usb: ehci-vf: make the USB host port usable Mehmet Fide
@ 2026-10-20 10:16 ` Mehmet Fide
  2026-10-20 10:16 ` [PATCH v7 2/9] usb: ehci-vf: take the controller index from the device tree Mehmet Fide
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Mehmet Fide @ 2026-10-20 10:16 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

From: Mehmet Fide <mehmet.fide@screeningeagle.com>

fdtdec_get_alias_seq() and fdtdec_get_alias_highest_id() compare the
alias name with the stem by strncmp() over the length of the stem, so
every alias that starts with the stem counts. On a Colibri VF50 the
aliases usbphy0 and usbphy1 matched the "usb" stem, the two USB
controllers were given the sequence numbers 2 and 3, and ehci-vf
indexed its two-entry tables with them. The live tree disagrees: there
of_alias_scan() splits an alias into the stem and the number and
of_alias_get_id() compares the stem exactly.

Match an alias only when the stem is followed by its number, as the
live tree does. A test covers both lookups with the sandbox aliases,
where "test" is a prefix of testbus3 and of the testfdt aliases.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---

Notes:
    Changes in v7:
    - Reviewed-by from Simon
    - rebased on main
    
    Changes in v6:
    - none
    
    Changes in v5:
    - new patch, from the review of the alias lookup in v4: the live and the
      flat implementation disagreed on a stem that is a prefix of an alias
    - the test calls fdtdec directly, which checkpatch warns about; the two
      lookups under test have no livetree form

 lib/fdtdec.c     | 43 ++++++++++++++++++++++++++++++-------------
 test/dm/fdtdec.c | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index d25535bf36c..5fe7e85a943 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -508,10 +508,29 @@ int fdtdec_add_aliases_for_id(const void *blob, const char *name,
 	return num_found;
 }
 
+/**
+ * alias_seq_of() - get the number an alias gives a stem
+ *
+ * @name: Alias name, e.g. "serial2"
+ * @base: Stem to match, e.g. "serial"
+ * Return: the number that follows the stem, -1 if @name is not @base
+ * followed by a number (usbphy0 is not a "usb" alias)
+ */
+static int alias_seq_of(const char *name, const char *base)
+{
+	int base_len = strlen(base);
+	const char *num = name + base_len;
+
+	if (strncmp(name, base, base_len) || !*num ||
+	    strspn(num, "0123456789") != strlen(num))
+		return -1;
+
+	return dectoul(num, NULL);
+}
+
 int fdtdec_get_alias_seq(const void *blob, const char *base, int offset,
 			 int *seqp)
 {
-	int base_len = strlen(base);
 	const char *find_name;
 	int find_namelen;
 	int prop_offset;
@@ -531,8 +550,11 @@ int fdtdec_get_alias_seq(const void *blob, const char *base, int offset,
 
 		prop = fdt_getprop_by_offset(blob, prop_offset, &name, &len);
 		debug("   - %s, %s\n", name, prop);
-		if (len < find_namelen || *prop != '/' || prop[len - 1] ||
-		    strncmp(name, base, base_len))
+		if (len < find_namelen || *prop != '/' || prop[len - 1])
+			continue;
+
+		val = alias_seq_of(name, base);
+		if (val < 0)
 			continue;
 
 		slash = strrchr(prop, '/');
@@ -549,12 +571,9 @@ int fdtdec_get_alias_seq(const void *blob, const char *base, int offset,
 				continue;
 		}
 
-		val = trailing_strtol(name);
-		if (val != -1) {
-			*seqp = val;
-			debug("Found seq %d\n", *seqp);
-			return 0;
-		}
+		*seqp = val;
+		debug("Found seq %d\n", *seqp);
+		return 0;
 	}
 
 	debug("Not found\n");
@@ -563,7 +582,6 @@ int fdtdec_get_alias_seq(const void *blob, const char *base, int offset,
 
 int fdtdec_get_alias_highest_id(const void *blob, const char *base)
 {
-	int base_len = strlen(base);
 	int prop_offset;
 	int aliases;
 	int max = -1;
@@ -580,11 +598,10 @@ int fdtdec_get_alias_highest_id(const void *blob, const char *base)
 
 		prop = fdt_getprop_by_offset(blob, prop_offset, &name, &len);
 		debug("   - %s, %s\n", name, prop);
-		if (*prop != '/' || prop[len - 1] ||
-		    strncmp(name, base, base_len))
+		if (*prop != '/' || prop[len - 1])
 			continue;
 
-		val = trailing_strtol(name);
+		val = alias_seq_of(name, base);
 		if (val > max) {
 			debug("Found seq %d\n", val);
 			max = val;
diff --git a/test/dm/fdtdec.c b/test/dm/fdtdec.c
index 495f57234a4..075f7e5471f 100644
--- a/test/dm/fdtdec.c
+++ b/test/dm/fdtdec.c
@@ -8,6 +8,7 @@
 #include <dm/of_extra.h>
 #include <dm/test.h>
 #include <fdt_support.h>
+#include <fdtdec.h>
 #include <mapmem.h>
 #include <smbios.h>
 #include <test/ut.h>
@@ -188,3 +189,37 @@ static int dm_test_fdt_chosen_smbios(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_fdt_chosen_smbios, UTF_SCAN_PDATA | UTF_SCAN_FDT);
+
+/* test fdtdec_get_alias_seq() and fdtdec_get_alias_highest_id() */
+static int dm_test_fdtdec_alias_seq(struct unit_test_state *uts)
+{
+	const void *blob = gd->fdt_blob;
+	int seq;
+
+	ut_assertok(fdtdec_get_alias_seq(blob, "testfdt",
+					 fdt_path_offset(blob,
+							 "/some-bus/c-test@1"),
+					 &seq));
+	ut_asserteq(12, seq);
+	ut_assertok(fdtdec_get_alias_seq(blob, "testbus",
+					 fdt_path_offset(blob, "/some-bus"),
+					 &seq));
+	ut_asserteq(3, seq);
+
+	/* the stem must be followed by the number: testbus3 is no "test" */
+	ut_asserteq(-ENOENT,
+		    fdtdec_get_alias_seq(blob, "test",
+					 fdt_path_offset(blob, "/some-bus"),
+					 &seq));
+	ut_asserteq(-ENOENT,
+		    fdtdec_get_alias_seq(blob, "spi",
+					 fdt_path_offset(blob, "/i2c@0"),
+					 &seq));
+
+	ut_asserteq(12, fdtdec_get_alias_highest_id(blob, "testfdt"));
+	ut_asserteq(3, fdtdec_get_alias_highest_id(blob, "testbus"));
+	ut_asserteq(-1, fdtdec_get_alias_highest_id(blob, "test"));
+
+	return 0;
+}
+DM_TEST(dm_test_fdtdec_alias_seq, UTF_SCAN_PDATA | UTF_SCAN_FDT);
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v7 2/9] usb: ehci-vf: take the controller index from the device tree
  2026-10-20 10:15 [PATCH v7 0/9] usb: ehci-vf: make the USB host port usable Mehmet Fide
  2026-10-20 10:16 ` [PATCH v7 1/9] fdtdec: match an alias to its stem only when the number follows it Mehmet Fide
@ 2026-10-20 10:16 ` Mehmet Fide
  2026-10-20 10:16 ` [PATCH v7 3/9] usb: ehci-vf: remove the code path for a build without DM_USB Mehmet Fide
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Mehmet Fide @ 2026-10-20 10:16 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

From: Mehmet Fide <mehmet.fide@screeningeagle.com>

"usb start" on a Colibri VF50 or VF61 ends in a data abort and a
watchdog reset.

vf_usb_of_to_plat() takes the controller index from dev_seq(), but the
usbphy0 and usbphy1 aliases count as "usb" aliases when the uclass
numbers its devices, so the two controllers get 2 and 3 and index past
the two entries of phy_bases[] and nc_reg_bases[]. usb_oc_config() then
writes through an address read from beyond the table.

Follow the fsl,usbphy phandle, as ehci-mx6 does, and map the PHY node to
the index of the table instead of trusting the sequence number.

Reviewed-by: Marek Vasut <marek.vasut+usb@mailbox.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---

Notes:
    Changes in v7:
    - the Reviewed-by moved above the Signed-off-by
    
    Changes in v6:
    - Reviewed-by from Marek and Simon
    
    Changes in v5:
    - none
    
    Changes in v4:
    - sent alone before, now patch 1 of the series
    - reworded the commit message, no code change
    - the test note moved here: on a Colibri VF50 V1.2A on an Iris carrier,
      "usb start" brings up the controller instead of resetting the board

 drivers/usb/host/ehci-vf.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index 96d1363a76e..32fe05920d0 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -221,8 +221,23 @@ static int vf_usb_of_to_plat(struct udevice *dev)
 	const void *dt_blob = gd->fdt_blob;
 	int node = dev_of_offset(dev);
 	const char *mode;
+	fdt_addr_t phy_addr;
+	ofnode phy_node;
+	int i;
 
-	priv->portnr = dev_seq(dev);
+	phy_node = ofnode_parse_phandle(dev_ofnode(dev), "fsl,usbphy", 0);
+	if (!ofnode_valid(phy_node))
+		return -EINVAL;
+
+	phy_addr = ofnode_get_addr(phy_node);
+	for (i = 0; i < ARRAY_SIZE(phy_bases); i++) {
+		if (phy_addr == phy_bases[i])
+			break;
+	}
+	if (i == ARRAY_SIZE(phy_bases))
+		return -EINVAL;
+
+	priv->portnr = i;
 
 	priv->ehci = dev_read_addr_ptr(dev);
 	mode = fdt_getprop(dt_blob, node, "dr_mode", NULL);
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v7 3/9] usb: ehci-vf: remove the code path for a build without DM_USB
  2026-10-20 10:15 [PATCH v7 0/9] usb: ehci-vf: make the USB host port usable Mehmet Fide
  2026-10-20 10:16 ` [PATCH v7 1/9] fdtdec: match an alias to its stem only when the number follows it Mehmet Fide
  2026-10-20 10:16 ` [PATCH v7 2/9] usb: ehci-vf: take the controller index from the device tree Mehmet Fide
@ 2026-10-20 10:16 ` Mehmet Fide
  2026-10-20 10:16 ` [PATCH v7 4/9] usb: ehci-vf: drop the empty bind hook Mehmet Fide
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Mehmet Fide @ 2026-10-20 10:16 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

From: Mehmet Fide <mehmet.fide@screeningeagle.com>

USB_EHCI_HCD selects USB_HOST, and USB_HOST selects DM_USB, so the
!CONFIG_IS_ENABLED(DM_USB) branch of this driver can never be selected.
It also cannot compile: ehci_hcd_init() calls ehci_vf_common_init() with
one argument while the function takes two, so the branch has been dead
since the controller was added as a second parameter.

Remove it, together with the board_usb_phy_mode() hook that no board
implements and nothing else calls.

Reviewed-by: Marek Vasut <marek.vasut+usb@mailbox.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---

Notes:
    Changes in v7:
    - Reviewed-by from Marek and Simon
    
    Changes in v6:
    - the commit message names USB_HOST as the option that selects DM_USB
    
    Changes in v5:
    - none
    
    Changes in v4:
    - none, rebased on next

 drivers/usb/host/ehci-vf.c | 49 --------------------------------------
 1 file changed, 49 deletions(-)

diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index 32fe05920d0..5d27318de62 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -128,11 +128,6 @@ static void usb_oc_config(int index)
 	setbits_le32(ctrl, UCTRL_OVER_CUR_DIS);
 }
 
-int __weak board_usb_phy_mode(int port)
-{
-	return 0;
-}
-
 int __weak board_ehci_hcd_init(int port)
 {
 	return 0;
@@ -155,49 +150,6 @@ int ehci_vf_common_init(struct usb_ehci *ehci, int index)
 	return 0;
 }
 
-#if !CONFIG_IS_ENABLED(DM_USB)
-int ehci_hcd_init(int index, enum usb_init_type init,
-		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
-{
-	struct usb_ehci *ehci;
-	enum usb_init_type type;
-	int ret;
-
-	if (index >= ARRAY_SIZE(nc_reg_bases))
-		return -EINVAL;
-
-	ehci = (struct usb_ehci *)nc_reg_bases[index];
-
-	ret = ehci_vf_common_init(index);
-	if (ret)
-		return ret;
-
-	*hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
-	*hcor = (struct ehci_hcor *)((uint32_t)*hccr +
-			HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
-
-	type = board_usb_phy_mode(index);
-	if (type != init)
-		return -ENODEV;
-
-	if (init == USB_INIT_DEVICE) {
-		setbits_le32(&ehci->usbmode, CM_DEVICE);
-		writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc);
-		setbits_le32(&ehci->portsc, USB_EN);
-	} else if (init == USB_INIT_HOST) {
-		setbits_le32(&ehci->usbmode, CM_HOST);
-		writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc);
-		setbits_le32(&ehci->portsc, USB_EN);
-	}
-
-	return 0;
-}
-
-int ehci_hcd_stop(int index)
-{
-	return 0;
-}
-#else
 /* Possible port types (dual role mode) */
 enum dr_mode {
 	DR_MODE_NONE = 0,
@@ -372,4 +324,3 @@ U_BOOT_DRIVER(ehci_vf) = {
 	.priv_auto	= sizeof(struct ehci_vf_priv_data),
 	.flags = DM_FLAG_ALLOC_PRIV_DMA,
 };
-#endif
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v7 4/9] usb: ehci-vf: drop the empty bind hook
  2026-10-20 10:15 [PATCH v7 0/9] usb: ehci-vf: make the USB host port usable Mehmet Fide
                   ` (2 preceding siblings ...)
  2026-10-20 10:16 ` [PATCH v7 3/9] usb: ehci-vf: remove the code path for a build without DM_USB Mehmet Fide
@ 2026-10-20 10:16 ` Mehmet Fide
  2026-10-20 10:16 ` [PATCH v7 5/9] dm: core: add ofnode_get_alias_seq() Mehmet Fide
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Mehmet Fide @ 2026-10-20 10:16 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

From: Mehmet Fide <mehmet.fide@screeningeagle.com>

vf_usb_bind() only returns 0. Its comment describes a hack that keeps
the second controller from taking sequence number 0, but no such code
is there, and an empty .bind cannot influence the numbering the uclass
does. Remove it.

Reviewed-by: Marek Vasut <marek.vasut+usb@mailbox.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---

Notes:
    Changes in v7:
    - the Reviewed-by moved above the Signed-off-by
    
    Changes in v6:
    - dropped the two Fixes tags, the hook was not empty at those commits
    - Reviewed-by from Marek and Simon
    
    Changes in v5:
    - none
    
    Changes in v4:
    - none, rebased on next

 drivers/usb/host/ehci-vf.c | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index 5d27318de62..e5f9ec0fdbb 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -261,20 +261,6 @@ static const struct ehci_ops vf_ehci_ops = {
 	.init_after_reset = vf_init_after_reset
 };
 
-static int vf_usb_bind(struct udevice *dev)
-{
-	/*
-	 * Without this hack, if we return ENODEV for USB Controller 0, on
-	 * probe for the next controller, USB Controller 1 will be given a
-	 * sequence number of 0. This conflicts with our requirement of
-	 * sequence numbers while initialising the peripherals.
-	 *
-	 * FIXME: Check that this still works OK with the new sequence numbers
-	 */
-
-	return 0;
-}
-
 static int ehci_usb_probe(struct udevice *dev)
 {
 	struct usb_plat *plat = dev_get_plat(dev);
@@ -315,7 +301,6 @@ U_BOOT_DRIVER(ehci_vf) = {
 	.name = "ehci_vf",
 	.id = UCLASS_USB,
 	.of_match = vf_usb_ids,
-	.bind = vf_usb_bind,
 	.probe = ehci_usb_probe,
 	.remove = ehci_deregister,
 	.ops = &ehci_usb_ops,
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v7 5/9] dm: core: add ofnode_get_alias_seq()
  2026-10-20 10:15 [PATCH v7 0/9] usb: ehci-vf: make the USB host port usable Mehmet Fide
                   ` (3 preceding siblings ...)
  2026-10-20 10:16 ` [PATCH v7 4/9] usb: ehci-vf: drop the empty bind hook Mehmet Fide
@ 2026-10-20 10:16 ` Mehmet Fide
  2026-10-20 10:16 ` [PATCH v7 6/9] usb: ehci-vf: use usb_get_dr_mode() Mehmet Fide
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Mehmet Fide @ 2026-10-20 10:16 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

From: Mehmet Fide <mehmet.fide@screeningeagle.com>

The sequence number an aliases entry gives a node can only be looked up
for a device, through dev_read_alias_seq(). A driver that has to know
the number of a node it does not own, one it reached through a phandle
for instance, has no livetree call for it and is left with fdtdec.

Move the body of dev_read_alias_seq() to the ofnode level and let both
of its variants call it. The flat lookup reads the tree the node belongs
to instead of gd->fdt_blob. The live lookup covered the control tree
only, as of_alias_scan() builds its table from that tree; a node of
another tree is now looked up in the /aliases node of its own tree. The
stem must match the alias exactly, which the previous patch makes the
flat lookup do as well.

Tests check the lookup on the live and on the flat tree, with a stem
that is only a prefix of an alias, and on another tree.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---

Notes:
    Changes in v7:
    - Reviewed-by from Simon
    - rebased on main
    
    Changes in v6:
    - none
    
    Changes in v5:
    - the stem must match the alias exactly, as patch 1 makes the flat
      lookup do; the kernel-doc says so and the test checks a prefix stem
    - a node outside the control tree is looked up in the /aliases node of
      its own tree on the live tree too; a test uses the other tree of the
      sandbox tests, which gains two aliases
    - the checkpatch note moved here: the warnings are in the body the patch
      moves, which is unchanged, and the check is the DM_TEST layout every
      test in test/dm/ofnode.c uses
    
    Changes in v4:
    - added a test, run on the live and on the flat tree
    - the kernel-doc no longer promises -ENOENT for a missing alias, the
      live tree returns -ENODEV

 arch/sandbox/dts/other.dts |  5 ++++
 drivers/core/of_access.c   | 42 ++++++++++++++++++++++++++++++++
 drivers/core/ofnode.c      | 20 ++++++++++++++++
 drivers/core/read.c        | 20 ++--------------
 include/dm/of_access.h     |  7 ++++--
 include/dm/ofnode.h        | 16 +++++++++++++
 include/dm/read.h          |  8 ++-----
 test/dm/ofnode.c           | 49 ++++++++++++++++++++++++++++++++++++++
 8 files changed, 141 insertions(+), 26 deletions(-)

diff --git a/arch/sandbox/dts/other.dts b/arch/sandbox/dts/other.dts
index 515d6348b3f..50597e2d570 100644
--- a/arch/sandbox/dts/other.dts
+++ b/arch/sandbox/dts/other.dts
@@ -15,6 +15,11 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 
+	aliases {
+		other-test0 = "/node";
+		other-test1 = "/node/subnode";
+	};
+
 	node {
 		other-phandle = <&target>;
 
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
index f910cc9a31b..2d19dfec25c 100644
--- a/drivers/core/of_access.c
+++ b/drivers/core/of_access.c
@@ -971,11 +971,53 @@ int of_alias_scan(void)
 	return 0;
 }
 
+/**
+ * of_tree_alias_get_id() - Get an alias id from the /aliases node of a tree
+ *
+ * The lookup table covers the control tree only; a node of another tree is
+ * looked up in the /aliases node of that tree.
+ *
+ * @root:	Root of the tree the node belongs to
+ * @np:		Pointer to the given device_node
+ * @stem:	Alias stem of the given device_node
+ * Return: alias ID, if found, else -ENODEV
+ */
+static int of_tree_alias_get_id(struct device_node *root,
+				const struct device_node *np, const char *stem)
+{
+	const struct device_node *aliases;
+	int stem_len = strlen(stem);
+	struct property *pp;
+
+	aliases = of_find_node_opts_by_path(root, "/aliases", NULL);
+	if (!aliases)
+		return -ENODEV;
+
+	for_each_property_of_node(aliases, pp) {
+		const char *num = pp->name + stem_len;
+		ulong id;
+
+		if (strncmp(pp->name, stem, stem_len) || !isdigit(*num) ||
+		    strict_strtoul(num, 10, &id))
+			continue;
+		if (of_find_node_opts_by_path(root, pp->value, NULL) == np)
+			return id;
+	}
+
+	return -ENODEV;
+}
+
 int of_alias_get_id(const struct device_node *np, const char *stem)
 {
+	struct device_node *root = (struct device_node *)np;
 	struct alias_prop *app;
 	int id = -ENODEV;
 
+	while (root->parent)
+		root = root->parent;
+	if (root != gd->of_root)
+		return of_tree_alias_get_id(root, np, stem);
+
 	mutex_lock(&of_mutex);
 	list_for_each_entry(app, &aliases_lookup, link) {
 		if (strcmp(app->stem, stem) != 0)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index b5d13c43db1..81d91ce5476 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -1233,6 +1233,26 @@ ofnode ofnode_get_aliases_node(const char *name)
 	return ofnode_path(prop);
 }
 
+int ofnode_get_alias_seq(ofnode node, const char *stem, int *seqp)
+{
+	int ret = -ENOTSUPP;
+
+	if (ofnode_is_np(node)) {
+		ret = of_alias_get_id(ofnode_to_np(node), stem);
+		if (ret >= 0) {
+			*seqp = ret;
+			ret = 0;
+		}
+	} else {
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+		ret = fdtdec_get_alias_seq(ofnode_to_fdt(node), stem,
+					   ofnode_to_offset(node), seqp);
+#endif
+	}
+
+	return ret;
+}
+
 int ofnode_get_child_count(ofnode parent)
 {
 	ofnode child;
diff --git a/drivers/core/read.c b/drivers/core/read.c
index ba48862f44b..985f6128d97 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -356,24 +356,8 @@ const void *dev_read_prop_by_prop(struct ofprop *prop,
 
 int dev_read_alias_seq(const struct udevice *dev, int *devnump)
 {
-	ofnode node = dev_ofnode(dev);
-	const char *uc_name = dev->uclass->uc_drv->name;
-	int ret = -ENOTSUPP;
-
-	if (ofnode_is_np(node)) {
-		ret = of_alias_get_id(ofnode_to_np(node), uc_name);
-		if (ret >= 0) {
-			*devnump = ret;
-			ret = 0;
-		}
-	} else {
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-		ret = fdtdec_get_alias_seq(gd->fdt_blob, uc_name,
-					   ofnode_to_offset(node), devnump);
-#endif
-	}
-
-	return ret;
+	return ofnode_get_alias_seq(dev_ofnode(dev),
+				    dev->uclass->uc_drv->name, devnump);
 }
 
 int dev_read_u32_array(const struct udevice *dev, const char *propname,
diff --git a/include/dm/of_access.h b/include/dm/of_access.h
index fe0de73d7e2..afbd32b2990 100644
--- a/include/dm/of_access.h
+++ b/include/dm/of_access.h
@@ -651,10 +651,13 @@ int of_alias_scan(void);
  * of_alias_get_id - Get alias id for the given device_node
  *
  * Travels the lookup table to get the alias id for the given device_node and
- * alias stem.
+ * alias stem. A node outside the control tree is looked up in the /aliases
+ * node of its own tree.
  *
  * @np:		Pointer to the given device_node
- * @stem:	Alias stem of the given device_node
+ * @stem:	Alias stem of the given device_node; an alias matches when its
+ *		name is the stem followed by the number, so "usb" does not match
+ *		usbphy0
  * Return: alias ID, if found, else -ENODEV
  */
 int of_alias_get_id(const struct device_node *np, const char *stem);
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index c905e86b283..c6eaebb4c75 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -1180,6 +1180,22 @@ const void *ofnode_read_aliases_prop(const char *propname, int *sizep);
  */
 ofnode ofnode_get_aliases_node(const char *propname);
 
+/**
+ * ofnode_get_alias_seq() - get the sequence number of a node from its alias
+ *
+ * The aliases node can name a node with a stem and a number, such as
+ * "serial2". This looks the node up in the aliases of its tree and returns
+ * the number.
+ *
+ * @node: Node to look for
+ * @stem: Alias stem, e.g. "serial". The stem must match exactly: an alias
+ *	matches when its name is the stem followed by the number, so "usb"
+ *	does not find usbphy0
+ * @seqp: Returns the sequence number of the alias, if found
+ * Return: 0 if a sequence number was found, -ve if not
+ */
+int ofnode_get_alias_seq(ofnode node, const char *stem, int *seqp);
+
 struct display_timing;
 /**
  * ofnode_decode_display_timing() - decode display timings
diff --git a/include/dm/read.h b/include/dm/read.h
index 12dcde6645c..d0c17c3d343 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -1168,12 +1168,8 @@ static inline const void *dev_read_prop_by_prop(struct ofprop *prop,
 
 static inline int dev_read_alias_seq(const struct udevice *dev, int *devnump)
 {
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-	return fdtdec_get_alias_seq(gd->fdt_blob, dev->uclass->uc_drv->name,
-				    dev_of_offset(dev), devnump);
-#else
-	return -ENOTSUPP;
-#endif
+	return ofnode_get_alias_seq(dev_ofnode(dev),
+				    dev->uclass->uc_drv->name, devnump);
 }
 
 static inline int dev_read_u32_array(const struct udevice *dev,
diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c
index 0f60c2a6281..d4c7380a412 100644
--- a/test/dm/ofnode.c
+++ b/test/dm/ofnode.c
@@ -523,6 +523,55 @@ static int dm_test_ofnode_read_aliases(struct unit_test_state *uts)
 }
 DM_TEST(dm_test_ofnode_read_aliases, UTF_SCAN_PDATA | UTF_SCAN_FDT);
 
+/* test ofnode_get_alias_seq() */
+static int dm_test_ofnode_get_alias_seq(struct unit_test_state *uts)
+{
+	int seq;
+
+	ut_assertok(ofnode_get_alias_seq(ofnode_path("/i2c@0"), "i2c", &seq));
+	ut_asserteq(0, seq);
+
+	ut_assertok(ofnode_get_alias_seq(ofnode_path("/some-bus/c-test@1"),
+					 "testfdt", &seq));
+	ut_asserteq(12, seq);
+
+	ut_assert(ofnode_get_alias_seq(ofnode_path("/i2c@0"), "spi", &seq) < 0);
+	ut_assert(ofnode_get_alias_seq(ofnode_path("/some-bus"), "testfdt",
+				       &seq) < 0);
+
+	/* the stem must match exactly: testbus3 is not a "test" alias */
+	ut_assert(ofnode_get_alias_seq(ofnode_path("/some-bus"), "test",
+				       &seq) < 0);
+
+	return 0;
+}
+DM_TEST(dm_test_ofnode_get_alias_seq, UTF_SCAN_FDT);
+
+/* test ofnode_get_alias_seq() with the 'other' tree */
+static int dm_test_ofnode_get_alias_seq_ot(struct unit_test_state *uts)
+{
+	oftree otree = get_other_oftree(uts);
+	int seq;
+
+	ut_assertok(ofnode_get_alias_seq(oftree_path(otree, "/node"),
+					 "other-test", &seq));
+	ut_asserteq(0, seq);
+	ut_assertok(ofnode_get_alias_seq(oftree_path(otree, "/node/subnode"),
+					 "other-test", &seq));
+	ut_asserteq(1, seq);
+
+	/* a prefix of the stem, and the aliases of the other tree */
+	ut_assert(ofnode_get_alias_seq(oftree_path(otree, "/node"), "other",
+				       &seq) < 0);
+	ut_assert(ofnode_get_alias_seq(oftree_path(otree, "/node"), "i2c",
+				       &seq) < 0);
+	ut_assert(ofnode_get_alias_seq(ofnode_path("/i2c@0"), "other-test",
+				       &seq) < 0);
+
+	return 0;
+}
+DM_TEST(dm_test_ofnode_get_alias_seq_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
+
 static int dm_test_ofnode_get_child_count(struct unit_test_state *uts)
 {
 	ofnode node, child_node;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v7 6/9] usb: ehci-vf: use usb_get_dr_mode()
  2026-10-20 10:15 [PATCH v7 0/9] usb: ehci-vf: make the USB host port usable Mehmet Fide
                   ` (4 preceding siblings ...)
  2026-10-20 10:16 ` [PATCH v7 5/9] dm: core: add ofnode_get_alias_seq() Mehmet Fide
@ 2026-10-20 10:16 ` Mehmet Fide
  2026-10-21  0:09   ` Marek Vasut
  2026-10-20 10:16 ` [PATCH v7 7/9] usb: ehci-vf: request the ID detect gpio through the device Mehmet Fide
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Mehmet Fide @ 2026-10-20 10:16 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

From: Mehmet Fide <mehmet.fide@screeningeagle.com>

The driver parses the dr_mode property itself, through the flat tree,
into an enum of its own that mirrors enum usb_dr_mode. Use
usb_get_dr_mode() and USB_DR_MODE_* instead, as ehci-mx6 does. A
missing property still means host and a value the driver does not
know still fails the probe with -EINVAL.

Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---

Notes:
    Changes in v7:
    - Marek's review: this patch only replaces the private enum and the
      strcmp() chain; the ID detect gpio moves to the next patch
    - a missing dr_mode property means host and an unknown value fails with
      -EINVAL again, as before the series; v6 made an unknown value host
    
    Changes in v6:
    - new patch, from the review of the register base patch in v5: the
      private enum duplicated USB_DR_MODE_*

 drivers/usb/host/ehci-vf.c | 40 ++++++++++++++------------------------
 1 file changed, 15 insertions(+), 25 deletions(-)

diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index e5f9ec0fdbb..1d7b3bdc285 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -21,8 +21,8 @@
 #include <asm/mach-imx/regs-usbphy.h>
 #include <linux/delay.h>
 #include <usb/ehci-ci.h>
-#include <linux/libfdt.h>
 #include <fdtdec.h>
+#include <linux/usb/otg.h>
 
 #include "ehci.h"
 
@@ -150,29 +150,19 @@ int ehci_vf_common_init(struct usb_ehci *ehci, int index)
 	return 0;
 }
 
-/* Possible port types (dual role mode) */
-enum dr_mode {
-	DR_MODE_NONE = 0,
-	DR_MODE_HOST,		/* supports host operation */
-	DR_MODE_DEVICE,		/* supports device operation */
-	DR_MODE_OTG,		/* supports both */
-};
-
 struct ehci_vf_priv_data {
 	struct ehci_ctrl ctrl;
 	struct usb_ehci *ehci;
 	struct gpio_desc cdet_gpio;
 	enum usb_init_type init_type;
-	enum dr_mode dr_mode;
+	enum usb_dr_mode dr_mode;
 	u32 portnr;
 };
 
 static int vf_usb_of_to_plat(struct udevice *dev)
 {
 	struct ehci_vf_priv_data *priv = dev_get_priv(dev);
-	const void *dt_blob = gd->fdt_blob;
 	int node = dev_of_offset(dev);
-	const char *mode;
 	fdt_addr_t phy_addr;
 	ofnode phy_node;
 	int i;
@@ -192,16 +182,16 @@ static int vf_usb_of_to_plat(struct udevice *dev)
 	priv->portnr = i;
 
 	priv->ehci = dev_read_addr_ptr(dev);
-	mode = fdt_getprop(dt_blob, node, "dr_mode", NULL);
-	if (mode) {
-		if (0 == strcmp(mode, "host")) {
-			priv->dr_mode = DR_MODE_HOST;
+	if (ofnode_read_string(dev_ofnode(dev), "dr_mode")) {
+		priv->dr_mode = usb_get_dr_mode(dev_ofnode(dev));
+		switch (priv->dr_mode) {
+		case USB_DR_MODE_HOST:
 			priv->init_type = USB_INIT_HOST;
-		} else if (0 == strcmp(mode, "peripheral")) {
-			priv->dr_mode = DR_MODE_DEVICE;
+			break;
+		case USB_DR_MODE_PERIPHERAL:
 			priv->init_type = USB_INIT_DEVICE;
-		} else if (0 == strcmp(mode, "otg")) {
-			priv->dr_mode = DR_MODE_OTG;
+			break;
+		case USB_DR_MODE_OTG:
 			/*
 			 * We set init_type to device by default when OTG
 			 * mode is requested. If a valid gpio is provided
@@ -209,17 +199,17 @@ static int vf_usb_of_to_plat(struct udevice *dev)
 			 * of the gpio pin.
 			 */
 			priv->init_type = USB_INIT_DEVICE;
-		} else {
-			debug("%s: Cannot decode dr_mode '%s'\n",
-			      __func__, mode);
+			break;
+		default:
+			debug("%s: Cannot decode dr_mode\n", __func__);
 			return -EINVAL;
 		}
 	} else {
-		priv->dr_mode = DR_MODE_HOST;
+		priv->dr_mode = USB_DR_MODE_HOST;
 		priv->init_type = USB_INIT_HOST;
 	}
 
-	if (priv->dr_mode == DR_MODE_OTG) {
+	if (priv->dr_mode == USB_DR_MODE_OTG) {
 		gpio_request_by_name_nodev(offset_to_ofnode(node),
 					   "fsl,cdet-gpio", 0, &priv->cdet_gpio,
 					   GPIOD_IS_IN);
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v7 7/9] usb: ehci-vf: request the ID detect gpio through the device
  2026-10-20 10:15 [PATCH v7 0/9] usb: ehci-vf: make the USB host port usable Mehmet Fide
                   ` (5 preceding siblings ...)
  2026-10-20 10:16 ` [PATCH v7 6/9] usb: ehci-vf: use usb_get_dr_mode() Mehmet Fide
@ 2026-10-20 10:16 ` Mehmet Fide
  2026-10-21  0:10   ` Marek Vasut
  2026-10-20 10:16 ` [PATCH v7 8/9] usb: ehci-vf: take the register bases from the device tree Mehmet Fide
  2026-10-20 10:16 ` [PATCH v7 9/9] usb: ehci-vf: enable the vbus supply of the port Mehmet Fide
  8 siblings, 1 reply; 21+ messages in thread
From: Mehmet Fide @ 2026-10-20 10:16 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

From: Mehmet Fide <mehmet.fide@screeningeagle.com>

The ID detect gpio of an OTG port is requested through the flat node,
the result is never checked and the gpio is never freed: a bad gpio
description or a failing read silently leaves the port in device mode,
and every probe after a "usb stop" fails to request the pin again and
reads it only because the failed request left the descriptor pointing
at it.

Request it through the device in the probe and fail the probe on any
error but a missing property, which keeps the port in device mode as
before. Free it in a remove hook and on the failing probe paths, so
that the probe after a "usb stop" can request it again.

The flat tree access was the last user of the global data pointer:
drop it.

Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---

Notes:
    Changes in v7:
    - new patch, split out of the previous one on Marek's review
    - gpio_request_by_name() and dm_gpio_get_value() are checked; only a
      missing property is tolerated
    - the gpio is requested in the probe and freed in a new remove hook and
      on the failing probe paths, so the probe after a "usb stop" can
      request it again

 drivers/usb/host/ehci-vf.c | 61 +++++++++++++++++++++++++-------------
 1 file changed, 40 insertions(+), 21 deletions(-)

diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index 1d7b3bdc285..edf100fc3b8 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -10,7 +10,6 @@
 #include <log.h>
 #include <usb.h>
 #include <errno.h>
-#include <asm/global_data.h>
 #include <linux/compiler.h>
 #include <asm/io.h>
 #include <asm-generic/gpio.h>
@@ -37,8 +36,6 @@
 #define UCMD_RUN_STOP		(1 << 0) /* controller run/stop */
 #define UCMD_RESET			(1 << 1) /* controller reset */
 
-DECLARE_GLOBAL_DATA_PTR;
-
 static const unsigned phy_bases[] = {
 	USB_PHY0_BASE_ADDR,
 	USB_PHY1_BASE_ADDR,
@@ -162,7 +159,6 @@ struct ehci_vf_priv_data {
 static int vf_usb_of_to_plat(struct udevice *dev)
 {
 	struct ehci_vf_priv_data *priv = dev_get_priv(dev);
-	int node = dev_of_offset(dev);
 	fdt_addr_t phy_addr;
 	ofnode phy_node;
 	int i;
@@ -209,18 +205,6 @@ static int vf_usb_of_to_plat(struct udevice *dev)
 		priv->init_type = USB_INIT_HOST;
 	}
 
-	if (priv->dr_mode == USB_DR_MODE_OTG) {
-		gpio_request_by_name_nodev(offset_to_ofnode(node),
-					   "fsl,cdet-gpio", 0, &priv->cdet_gpio,
-					   GPIOD_IS_IN);
-		if (dm_gpio_is_valid(&priv->cdet_gpio)) {
-			if (dm_gpio_get_value(&priv->cdet_gpio))
-				priv->init_type = USB_INIT_DEVICE;
-			else
-				priv->init_type = USB_INIT_HOST;
-		}
-	}
-
 	return 0;
 }
 
@@ -260,12 +244,27 @@ static int ehci_usb_probe(struct udevice *dev)
 	struct ehci_hcor *hcor;
 	int ret;
 
+	if (priv->dr_mode == USB_DR_MODE_OTG) {
+		ret = gpio_request_by_name(dev, "fsl,cdet-gpio", 0,
+					   &priv->cdet_gpio, GPIOD_IS_IN);
+		if (ret && ret != -ENOENT)
+			return ret;
+		if (!ret) {
+			ret = dm_gpio_get_value(&priv->cdet_gpio);
+			if (ret < 0)
+				goto err_gpio;
+			priv->init_type = ret ? USB_INIT_DEVICE : USB_INIT_HOST;
+		}
+	}
+
 	ret = ehci_vf_common_init(ehci, priv->portnr);
 	if (ret)
-		return ret;
+		goto err_gpio;
 
-	if (priv->init_type != plat->init_type)
-		return -ENODEV;
+	if (priv->init_type != plat->init_type) {
+		ret = -ENODEV;
+		goto err_gpio;
+	}
 
 	if (priv->init_type == USB_INIT_HOST) {
 		setbits_le32(&ehci->usbmode, CM_HOST);
@@ -279,7 +278,17 @@ static int ehci_usb_probe(struct udevice *dev)
 	hcor = (struct ehci_hcor *)((uint32_t)hccr +
 				HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
 
-	return ehci_register(dev, hccr, hcor, &vf_ehci_ops, 0, priv->init_type);
+	ret = ehci_register(dev, hccr, hcor, &vf_ehci_ops, 0, priv->init_type);
+	if (ret)
+		goto err_gpio;
+
+	return 0;
+
+err_gpio:
+	if (dm_gpio_is_valid(&priv->cdet_gpio))
+		dm_gpio_free(dev, &priv->cdet_gpio);
+
+	return ret;
 }
 
 static const struct udevice_id vf_usb_ids[] = {
@@ -287,12 +296,22 @@ static const struct udevice_id vf_usb_ids[] = {
 	{ }
 };
 
+static int ehci_usb_remove(struct udevice *dev)
+{
+	struct ehci_vf_priv_data *priv = dev_get_priv(dev);
+
+	if (dm_gpio_is_valid(&priv->cdet_gpio))
+		dm_gpio_free(dev, &priv->cdet_gpio);
+
+	return ehci_deregister(dev);
+}
+
 U_BOOT_DRIVER(ehci_vf) = {
 	.name = "ehci_vf",
 	.id = UCLASS_USB,
 	.of_match = vf_usb_ids,
 	.probe = ehci_usb_probe,
-	.remove = ehci_deregister,
+	.remove = ehci_usb_remove,
 	.ops = &ehci_usb_ops,
 	.of_to_plat = vf_usb_of_to_plat,
 	.plat_auto	= sizeof(struct usb_plat),
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v7 8/9] usb: ehci-vf: take the register bases from the device tree
  2026-10-20 10:15 [PATCH v7 0/9] usb: ehci-vf: make the USB host port usable Mehmet Fide
                   ` (6 preceding siblings ...)
  2026-10-20 10:16 ` [PATCH v7 7/9] usb: ehci-vf: request the ID detect gpio through the device Mehmet Fide
@ 2026-10-20 10:16 ` Mehmet Fide
  2026-10-21  0:13   ` Marek Vasut
  2026-10-20 10:16 ` [PATCH v7 9/9] usb: ehci-vf: enable the vbus supply of the port Mehmet Fide
  8 siblings, 1 reply; 21+ messages in thread
From: Mehmet Fide @ 2026-10-20 10:16 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

From: Mehmet Fide <mehmet.fide@screeningeagle.com>

The driver keeps its own tables of PHY and controller base addresses
and reaches the anatop block through a hardcoded address, although the
device tree describes all three: the controller points at its PHY and
usbmisc nodes, and the PHY at its anatop.

Read them from there and drop the tables: the two phandles of the
controller node through dev_read_phandle_with_args(), the anatop one
from the PHY node. The helpers take the private data instead of single
addresses. The port number stays only for the choice between PLL3 and
PLL7, which the device tree does not express, and now comes from the
usbphy alias of the PHY node.

The usbmisc node already starts at the non-core registers, so the
driver no longer adds an offset to reach them.

Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---

Notes:
    Changes in v7:
    - portnr keeps its u32 type, Marek's review; the alias lookup writes a
      local int
    - adapted to the split of the previous patch, no other code change
    
    Changes in v6:
    - the phandles of the controller node are read with
      dev_read_phandle_with_args()
    - the helpers take the private data, not single addresses
    - the dr_mode enum this patch used to move is gone, see the new patch
      before this one
    
    Changes in v5:
    - the PHY node is looked up with the "usbphy" stem: the uclass name
      "usb" found usbphy0 only through the prefix match of the flat lookup
    
    Changes in v4:
    - rebased on next
    - dropped two comments that repeated the commit message
    - reworded the commit message and took the note on the previous version
      out of it

 drivers/usb/host/ehci-vf.c | 135 ++++++++++++++++++++-----------------
 1 file changed, 74 insertions(+), 61 deletions(-)

diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index edf100fc3b8..e67eae834b0 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -20,13 +20,10 @@
 #include <asm/mach-imx/regs-usbphy.h>
 #include <linux/delay.h>
 #include <usb/ehci-ci.h>
-#include <fdtdec.h>
 #include <linux/usb/otg.h>
 
 #include "ehci.h"
 
-#define USB_NC_REG_OFFSET				0x00000800
-
 #define ANADIG_PLL_CTRL_EN_USB_CLKS		(1 << 6)
 
 #define UCTRL_OVER_CUR_POL	(1 << 8) /* OTG Polarity of Overcurrent */
@@ -36,31 +33,29 @@
 #define UCMD_RUN_STOP		(1 << 0) /* controller run/stop */
 #define UCMD_RESET			(1 << 1) /* controller reset */
 
-static const unsigned phy_bases[] = {
-	USB_PHY0_BASE_ADDR,
-	USB_PHY1_BASE_ADDR,
-};
-
-static const unsigned nc_reg_bases[] = {
-	USBC0_BASE_ADDR,
-	USBC1_BASE_ADDR,
+struct ehci_vf_priv_data {
+	struct ehci_ctrl ctrl;
+	struct usb_ehci *ehci;
+	struct gpio_desc cdet_gpio;
+	enum usb_init_type init_type;
+	enum usb_dr_mode dr_mode;
+	struct anadig_reg __iomem *anatop_addr;
+	void __iomem *phy_addr;
+	void __iomem *misc_addr;
+	u32 portnr;
 };
 
-static void usb_internal_phy_clock_gate(int index)
+static void usb_internal_phy_clock_gate(struct ehci_vf_priv_data *priv)
 {
-	void __iomem *phy_reg;
-
-	phy_reg = (void __iomem *)phy_bases[index];
-	clrbits_le32(phy_reg + USBPHY_CTRL, USBPHY_CTRL_CLKGATE);
+	clrbits_le32(priv->phy_addr + USBPHY_CTRL, USBPHY_CTRL_CLKGATE);
 }
 
-static void usb_power_config(int index)
+static void usb_power_config(struct ehci_vf_priv_data *priv)
 {
-	struct anadig_reg __iomem *anadig =
-		(struct anadig_reg __iomem *)ANADIG_BASE_ADDR;
+	struct anadig_reg __iomem *anadig = priv->anatop_addr;
 	void __iomem *pll_ctrl;
 
-	switch (index) {
+	switch (priv->portnr) {
 	case 0:
 		pll_ctrl = &anadig->pll3_ctrl;
 		clrbits_le32(pll_ctrl, ANADIG_PLL3_CTRL_BYPASS);
@@ -80,15 +75,14 @@ static void usb_power_config(int index)
 	}
 }
 
-static void usb_phy_enable(int index, struct usb_ehci *ehci)
+static void usb_phy_enable(struct ehci_vf_priv_data *priv)
 {
-	void __iomem *phy_reg;
+	void __iomem *phy_reg = priv->phy_addr;
 	void __iomem *phy_ctrl;
 	void __iomem *usb_cmd;
 
-	phy_reg = (void __iomem *)phy_bases[index];
 	phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL);
-	usb_cmd = (void __iomem *)&ehci->usbcmd;
+	usb_cmd = (void __iomem *)&priv->ehci->usbcmd;
 
 	/* Stop then Reset */
 	clrbits_le32(usb_cmd, UCMD_RUN_STOP);
@@ -115,14 +109,10 @@ static void usb_phy_enable(int index, struct usb_ehci *ehci)
 		 USBPHY_CTRL_ENUTMILEVEL3);
 }
 
-static void usb_oc_config(int index)
+static void usb_oc_config(struct ehci_vf_priv_data *priv)
 {
-	void __iomem *ctrl;
-
-	ctrl = (void __iomem *)(nc_reg_bases[index] + USB_NC_REG_OFFSET);
-
-	setbits_le32(ctrl, UCTRL_OVER_CUR_POL);
-	setbits_le32(ctrl, UCTRL_OVER_CUR_DIS);
+	setbits_le32(priv->misc_addr, UCTRL_OVER_CUR_POL);
+	setbits_le32(priv->misc_addr, UCTRL_OVER_CUR_DIS);
 }
 
 int __weak board_ehci_hcd_init(int port)
@@ -130,52 +120,75 @@ int __weak board_ehci_hcd_init(int port)
 	return 0;
 }
 
-int ehci_vf_common_init(struct usb_ehci *ehci, int index)
+static int ehci_vf_common_init(struct ehci_vf_priv_data *priv)
 {
 	int ret;
 
 	/* Do board specific initialisation */
-	ret = board_ehci_hcd_init(index);
+	ret = board_ehci_hcd_init(priv->portnr);
 	if (ret)
 		return ret;
 
-	usb_power_config(index);
-	usb_oc_config(index);
-	usb_internal_phy_clock_gate(index);
-	usb_phy_enable(index, ehci);
+	usb_power_config(priv);
+	usb_oc_config(priv);
+	usb_internal_phy_clock_gate(priv);
+	usb_phy_enable(priv);
 
 	return 0;
 }
 
-struct ehci_vf_priv_data {
-	struct ehci_ctrl ctrl;
-	struct usb_ehci *ehci;
-	struct gpio_desc cdet_gpio;
-	enum usb_init_type init_type;
-	enum usb_dr_mode dr_mode;
-	u32 portnr;
-};
-
-static int vf_usb_of_to_plat(struct udevice *dev)
+static int vf_parse_dt_addrs(struct udevice *dev)
 {
 	struct ehci_vf_priv_data *priv = dev_get_priv(dev);
-	fdt_addr_t phy_addr;
-	ofnode phy_node;
-	int i;
+	struct ofnode_phandle_args phy, misc;
+	ofnode anatop_node;
+	fdt_addr_t addr;
+	int seq, ret;
+
+	ret = dev_read_phandle_with_args(dev, "fsl,usbphy", NULL, 0, 0, &phy);
+	if (ret)
+		return ret;
+
+	ret = dev_read_phandle_with_args(dev, "fsl,usbmisc", NULL, 0, 0,
+					 &misc);
+	if (ret)
+		return ret;
 
-	phy_node = ofnode_parse_phandle(dev_ofnode(dev), "fsl,usbphy", 0);
-	if (!ofnode_valid(phy_node))
+	anatop_node = ofnode_parse_phandle(phy.node, "fsl,anatop", 0);
+	if (!ofnode_valid(anatop_node))
 		return -EINVAL;
 
-	phy_addr = ofnode_get_addr(phy_node);
-	for (i = 0; i < ARRAY_SIZE(phy_bases); i++) {
-		if (phy_addr == phy_bases[i])
-			break;
-	}
-	if (i == ARRAY_SIZE(phy_bases))
+	ret = ofnode_get_alias_seq(phy.node, "usbphy", &seq);
+	if (ret)
+		return ret;
+	priv->portnr = seq;
+
+	addr = ofnode_get_addr(phy.node);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+	priv->phy_addr = (void __iomem *)addr;
+
+	addr = ofnode_get_addr(misc.node);
+	if (addr == FDT_ADDR_T_NONE)
 		return -EINVAL;
+	priv->misc_addr = (void __iomem *)addr;
 
-	priv->portnr = i;
+	addr = ofnode_get_addr(anatop_node);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+	priv->anatop_addr = (struct anadig_reg __iomem *)addr;
+
+	return 0;
+}
+
+static int vf_usb_of_to_plat(struct udevice *dev)
+{
+	struct ehci_vf_priv_data *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = vf_parse_dt_addrs(dev);
+	if (ret)
+		return ret;
 
 	priv->ehci = dev_read_addr_ptr(dev);
 	if (ofnode_read_string(dev_ofnode(dev), "dr_mode")) {
@@ -215,7 +228,7 @@ static int vf_init_after_reset(struct ehci_ctrl *dev)
 	struct usb_ehci *ehci = priv->ehci;
 	int ret;
 
-	ret = ehci_vf_common_init(priv->ehci, priv->portnr);
+	ret = ehci_vf_common_init(priv);
 	if (ret)
 		return ret;
 
@@ -257,7 +270,7 @@ static int ehci_usb_probe(struct udevice *dev)
 		}
 	}
 
-	ret = ehci_vf_common_init(ehci, priv->portnr);
+	ret = ehci_vf_common_init(priv);
 	if (ret)
 		goto err_gpio;
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v7 9/9] usb: ehci-vf: enable the vbus supply of the port
  2026-10-20 10:15 [PATCH v7 0/9] usb: ehci-vf: make the USB host port usable Mehmet Fide
                   ` (7 preceding siblings ...)
  2026-10-20 10:16 ` [PATCH v7 8/9] usb: ehci-vf: take the register bases from the device tree Mehmet Fide
@ 2026-10-20 10:16 ` Mehmet Fide
  2026-10-21  0:13   ` Marek Vasut
  8 siblings, 1 reply; 21+ messages in thread
From: Mehmet Fide @ 2026-10-20 10:16 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

From: Mehmet Fide <mehmet.fide@screeningeagle.com>

The driver never enables the vbus-supply of its port, so on boards that
switch VBUS through a regulator, such as the Colibri VF50 and VF61
carriers, the port stays unpowered and no device is found.

Do what ehci-mx6 does: look the regulator up in probe, enable it in
host mode, disable it in device mode, and turn it off on remove. A
missing vbus-supply or a build without DM_REGULATOR is fine; any other
lookup error fails the probe instead of leaving the port dead.

Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---

Notes:
    Changes in v7:
    - the Reviewed-by of Marek and Simon on v6 is dropped: the VBUS code is
      unchanged, but the remove hook now comes from patch 7 and this patch
      adds its VBUS line to it
    
    Changes in v6:
    - dev_err() and dev_dbg() for the two messages; the reset hook reaches
      the device through the private data
    
    Changes in v5:
    - none
    
    Changes in v4:
    - enable VBUS in the reset hook only, as ehci-mx6 does: enabling it in
      the shared init as well counted two enables per probe, so "usb stop"
      never switched it off
    - the dm core patch it needed is dropped, next claims the regulator
      GPIO at probe time
    - reworded the commit message

 drivers/usb/host/ehci-vf.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index e67eae834b0..ca2023cf7f5 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -20,7 +20,9 @@
 #include <asm/mach-imx/regs-usbphy.h>
 #include <linux/delay.h>
 #include <usb/ehci-ci.h>
+#include <power/regulator.h>
 #include <linux/usb/otg.h>
+#include <dm/device_compat.h>
 
 #include "ehci.h"
 
@@ -42,6 +44,8 @@ struct ehci_vf_priv_data {
 	struct anadig_reg __iomem *anatop_addr;
 	void __iomem *phy_addr;
 	void __iomem *misc_addr;
+	struct udevice *vbus_supply;
+	struct udevice *dev;
 	u32 portnr;
 };
 
@@ -221,9 +225,9 @@ static int vf_usb_of_to_plat(struct udevice *dev)
 	return 0;
 }
 
-static int vf_init_after_reset(struct ehci_ctrl *dev)
+static int vf_init_after_reset(struct ehci_ctrl *ctrl)
 {
-	struct ehci_vf_priv_data *priv = dev->priv;
+	struct ehci_vf_priv_data *priv = ctrl->priv;
 	enum usb_init_type type = priv->init_type;
 	struct usb_ehci *ehci = priv->ehci;
 	int ret;
@@ -232,6 +236,13 @@ static int vf_init_after_reset(struct ehci_ctrl *dev)
 	if (ret)
 		return ret;
 
+	ret = regulator_set_enable_if_allowed(priv->vbus_supply,
+					      type != USB_INIT_DEVICE);
+	if (ret && ret != -ENOSYS) {
+		dev_err(priv->dev, "cannot enable the VBUS supply: %d\n", ret);
+		return ret;
+	}
+
 	if (type == USB_INIT_DEVICE)
 		return 0;
 
@@ -257,6 +268,16 @@ static int ehci_usb_probe(struct udevice *dev)
 	struct ehci_hcor *hcor;
 	int ret;
 
+	priv->dev = dev;
+	ret = device_get_supply_regulator(dev, "vbus-supply",
+					  &priv->vbus_supply);
+	if (ret == -ENOENT || ret == -ENOSYS) {
+		dev_dbg(dev, "no VBUS supply\n");
+	} else if (ret) {
+		dev_err(dev, "cannot get the VBUS supply: %d\n", ret);
+		return ret;
+	}
+
 	if (priv->dr_mode == USB_DR_MODE_OTG) {
 		ret = gpio_request_by_name(dev, "fsl,cdet-gpio", 0,
 					   &priv->cdet_gpio, GPIOD_IS_IN);
@@ -313,6 +334,8 @@ static int ehci_usb_remove(struct udevice *dev)
 {
 	struct ehci_vf_priv_data *priv = dev_get_priv(dev);
 
+	regulator_set_enable_if_allowed(priv->vbus_supply, false);
+
 	if (dm_gpio_is_valid(&priv->cdet_gpio))
 		dm_gpio_free(dev, &priv->cdet_gpio);
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH v7 6/9] usb: ehci-vf: use usb_get_dr_mode()
  2026-10-20 10:16 ` [PATCH v7 6/9] usb: ehci-vf: use usb_get_dr_mode() Mehmet Fide
@ 2026-10-21  0:09   ` Marek Vasut
  2026-10-21 11:59     ` Mehmet Fide
  0 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2026-10-21  0:09 UTC (permalink / raw)
  To: Mehmet Fide, Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

On 10/20/26 12:16 PM, Mehmet Fide wrote:

[...]

> @@ -192,16 +182,16 @@ static int vf_usb_of_to_plat(struct udevice *dev)
>   	priv->portnr = i;
>   
>   	priv->ehci = dev_read_addr_ptr(dev);
> -	mode = fdt_getprop(dt_blob, node, "dr_mode", NULL);
> -	if (mode) {
> -		if (0 == strcmp(mode, "host")) {
> -			priv->dr_mode = DR_MODE_HOST;
> +	if (ofnode_read_string(dev_ofnode(dev), "dr_mode")) {
> +		priv->dr_mode = usb_get_dr_mode(dev_ofnode(dev));

usb_get_dr_mode(dev_ofnode(dev))

> +		switch (priv->dr_mode) {
> +		case USB_DR_MODE_HOST:
>   			priv->init_type = USB_INIT_HOST;
> -		} else if (0 == strcmp(mode, "peripheral")) {
> -			priv->dr_mode = DR_MODE_DEVICE;
> +			break;
> +		case USB_DR_MODE_PERIPHERAL:
[...]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v7 7/9] usb: ehci-vf: request the ID detect gpio through the device
  2026-10-20 10:16 ` [PATCH v7 7/9] usb: ehci-vf: request the ID detect gpio through the device Mehmet Fide
@ 2026-10-21  0:10   ` Marek Vasut
  0 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2026-10-21  0:10 UTC (permalink / raw)
  To: Mehmet Fide, Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

On 10/20/26 12:16 PM, Mehmet Fide wrote:
> From: Mehmet Fide <mehmet.fide@screeningeagle.com>
> 
> The ID detect gpio of an OTG port is requested through the flat node,
> the result is never checked and the gpio is never freed: a bad gpio
> description or a failing read silently leaves the port in device mode,
> and every probe after a "usb stop" fails to request the pin again and
> reads it only because the failed request left the descriptor pointing
> at it.
> 
> Request it through the device in the probe and fail the probe on any
> error but a missing property, which keeps the port in device mode as
> before. Free it in a remove hook and on the failing probe paths, so
> that the probe after a "usb stop" can request it again.
> 
> The flat tree access was the last user of the global data pointer:
> drop it.
> 
> Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
Reviewed-by: Marek Vasut <marek.vasut+usb@mailbox.org>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v7 9/9] usb: ehci-vf: enable the vbus supply of the port
  2026-10-20 10:16 ` [PATCH v7 9/9] usb: ehci-vf: enable the vbus supply of the port Mehmet Fide
@ 2026-10-21  0:13   ` Marek Vasut
  2026-10-21 11:59     ` Mehmet Fide
  0 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2026-10-21  0:13 UTC (permalink / raw)
  To: Mehmet Fide, Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

On 10/20/26 12:16 PM, Mehmet Fide wrote:

[...]

> +++ b/drivers/usb/host/ehci-vf.c
> @@ -20,7 +20,9 @@
>   #include <asm/mach-imx/regs-usbphy.h>
>   #include <linux/delay.h>
>   #include <usb/ehci-ci.h>
> +#include <power/regulator.h>
>   #include <linux/usb/otg.h>
> +#include <dm/device_compat.h>

Keep the list sorted.

>   #include "ehci.h"
>   
> @@ -42,6 +44,8 @@ struct ehci_vf_priv_data {
>   	struct anadig_reg __iomem *anatop_addr;
>   	void __iomem *phy_addr;
>   	void __iomem *misc_addr;
> +	struct udevice *vbus_supply;
> +	struct udevice *dev;
>   	u32 portnr;
>   };
>   
> @@ -221,9 +225,9 @@ static int vf_usb_of_to_plat(struct udevice *dev)
>   	return 0;
>   }
>   
> -static int vf_init_after_reset(struct ehci_ctrl *dev)
> +static int vf_init_after_reset(struct ehci_ctrl *ctrl)

Is this rename necessary ?

>   {
> -	struct ehci_vf_priv_data *priv = dev->priv;
> +	struct ehci_vf_priv_data *priv = ctrl->priv;
>   	enum usb_init_type type = priv->init_type;
>   	struct usb_ehci *ehci = priv->ehci;
>   	int ret;
[...]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v7 8/9] usb: ehci-vf: take the register bases from the device tree
  2026-10-20 10:16 ` [PATCH v7 8/9] usb: ehci-vf: take the register bases from the device tree Mehmet Fide
@ 2026-10-21  0:13   ` Marek Vasut
  0 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2026-10-21  0:13 UTC (permalink / raw)
  To: Mehmet Fide, Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

On 10/20/26 12:16 PM, Mehmet Fide wrote:
> From: Mehmet Fide <mehmet.fide@screeningeagle.com>
> 
> The driver keeps its own tables of PHY and controller base addresses
> and reaches the anatop block through a hardcoded address, although the
> device tree describes all three: the controller points at its PHY and
> usbmisc nodes, and the PHY at its anatop.
> 
> Read them from there and drop the tables: the two phandles of the
> controller node through dev_read_phandle_with_args(), the anatop one
> from the PHY node. The helpers take the private data instead of single
> addresses. The port number stays only for the choice between PLL3 and
> PLL7, which the device tree does not express, and now comes from the
> usbphy alias of the PHY node.
> 
> The usbmisc node already starts at the non-core registers, so the
> driver no longer adds an offset to reach them.
> 
> Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
Reviewed-by: Marek Vasut <marek.vasut+usb@mailbox.org>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v7 6/9] usb: ehci-vf: use usb_get_dr_mode()
  2026-10-21  0:09   ` Marek Vasut
@ 2026-10-21 11:59     ` Mehmet Fide
  2026-10-21 12:07       ` Marek Vasut
  0 siblings, 1 reply; 21+ messages in thread
From: Mehmet Fide @ 2026-10-21 11:59 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

Hi Marek,

On 2026-10-21, Marek Vasut wrote:
>> +	if (ofnode_read_string(dev_ofnode(dev), "dr_mode")) {
>> +		priv->dr_mode = usb_get_dr_mode(dev_ofnode(dev));
>
> usb_get_dr_mode(dev_ofnode(dev))

I am not sure what you mean here. Could you say a bit more?

Thanks,
Mehmet

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v7 9/9] usb: ehci-vf: enable the vbus supply of the port
  2026-10-21  0:13   ` Marek Vasut
@ 2026-10-21 11:59     ` Mehmet Fide
  0 siblings, 0 replies; 21+ messages in thread
From: Mehmet Fide @ 2026-10-21 11:59 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

Hi Marek,

On 2026-10-21, Marek Vasut wrote:
>> +#include <power/regulator.h>
>>   #include <linux/usb/otg.h>
>> +#include <dm/device_compat.h>
>
> Keep the list sorted.

Will do in v8.

>> -static int vf_init_after_reset(struct ehci_ctrl *dev)
>> +static int vf_init_after_reset(struct ehci_ctrl *ctrl)
>
> Is this rename necessary ?

No, v8 drops it.

Thanks,
Mehmet

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v7 6/9] usb: ehci-vf: use usb_get_dr_mode()
  2026-10-21 11:59     ` Mehmet Fide
@ 2026-10-21 12:07       ` Marek Vasut
  2026-10-21 12:21         ` Mehmet Fide
  0 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2026-10-21 12:07 UTC (permalink / raw)
  To: Mehmet Fide
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

On 10/21/26 1:59 PM, Mehmet Fide wrote:
> Hi Marek,
> 
> On 2026-10-21, Marek Vasut wrote:
>>> +	if (ofnode_read_string(dev_ofnode(dev), "dr_mode")) {
>>> +		priv->dr_mode = usb_get_dr_mode(dev_ofnode(dev));
>>
>> usb_get_dr_mode(dev_ofnode(dev))
> 
> I am not sure what you mean here. Could you say a bit more?
You probably don't need the ofnode_read_string(...) above, it is part of 
the usb_get_dr_mode(dev_ofnode(dev)) already.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v7 6/9] usb: ehci-vf: use usb_get_dr_mode()
  2026-10-21 12:07       ` Marek Vasut
@ 2026-10-21 12:21         ` Mehmet Fide
  2026-10-21 13:17           ` Marek Vasut
  0 siblings, 1 reply; 21+ messages in thread
From: Mehmet Fide @ 2026-10-21 12:21 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

Hi Marek,

On 2026-10-21, Marek Vasut wrote:
> You probably don't need the ofnode_read_string(...) above, it is part of
> the usb_get_dr_mode(dev_ofnode(dev)) already.

Then a missing dr_mode fails the probe like an unknown one, where the
old code took it as host. Both USB nodes in vfxxx.dtsi set dr_mode, so
no in-tree board changes. Fine with you for v8?

Thanks,
Mehmet

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v7 6/9] usb: ehci-vf: use usb_get_dr_mode()
  2026-10-21 12:21         ` Mehmet Fide
@ 2026-10-21 13:17           ` Marek Vasut
  2026-10-21 18:41             ` Mehmet Fide
  0 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2026-10-21 13:17 UTC (permalink / raw)
  To: Mehmet Fide
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

On 10/21/26 2:21 PM, Mehmet Fide wrote:

Hello Mehmet,

> On 2026-10-21, Marek Vasut wrote:
>> You probably don't need the ofnode_read_string(...) above, it is part of
>> the usb_get_dr_mode(dev_ofnode(dev)) already.
> 
> Then a missing dr_mode fails the probe like an unknown one, where the
> old code took it as host. Both USB nodes in vfxxx.dtsi set dr_mode, so
> no in-tree board changes. Fine with you for v8?
Hmmmm, I see your point. And I think you need that fallback from missing 
dr_mode to HOST for legacy DTs, right ?

Can we do this ?

priv->dr_mode = usb_get_dr_mode(dev_ofnode(dev));
/* Handle legacy DTs without dr_mode property, fall back to host */
if (priv->dr_mode == USB_DR_MODE_UNKNOWN)
   priv->dr_mode = USB_DR_MODE_HOST;

switch (priv->dr_mode) {
case USB_DR_MODE_HOST:
...
}

What do you think ?

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v7 6/9] usb: ehci-vf: use usb_get_dr_mode()
  2026-10-21 13:17           ` Marek Vasut
@ 2026-10-21 18:41             ` Mehmet Fide
  2026-10-21 18:56               ` Marek Vasut
  0 siblings, 1 reply; 21+ messages in thread
From: Mehmet Fide @ 2026-10-21 18:41 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

Hi Marek,

On 2026-10-21, Marek Vasut wrote:
> Can we do this ?
>
> priv->dr_mode = usb_get_dr_mode(dev_ofnode(dev));
> /* Handle legacy DTs without dr_mode property, fall back to host */
> if (priv->dr_mode == USB_DR_MODE_UNKNOWN)
>    priv->dr_mode = USB_DR_MODE_HOST;

Yes, v8 does it this way.

Thanks,
Mehmet

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v7 6/9] usb: ehci-vf: use usb_get_dr_mode()
  2026-10-21 18:41             ` Mehmet Fide
@ 2026-10-21 18:56               ` Marek Vasut
  0 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2026-10-21 18:56 UTC (permalink / raw)
  To: Mehmet Fide, Marek Vasut
  Cc: Simon Glass, Tom Rini, Fabio Estevam, Stefan Agner,
	Francesco Dolcini, u-boot, mehmet.fide

On 10/21/26 8:41 PM, Mehmet Fide wrote:
> Hi Marek,
> 
> On 2026-10-21, Marek Vasut wrote:
>> Can we do this ?
>>
>> priv->dr_mode = usb_get_dr_mode(dev_ofnode(dev));
>> /* Handle legacy DTs without dr_mode property, fall back to host */
>> if (priv->dr_mode == USB_DR_MODE_UNKNOWN)
>>     priv->dr_mode = USB_DR_MODE_HOST;
> 
> Yes, v8 does it this way.
Thank you

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2026-10-22  6:49 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-20 10:15 [PATCH v7 0/9] usb: ehci-vf: make the USB host port usable Mehmet Fide
2026-10-20 10:16 ` [PATCH v7 1/9] fdtdec: match an alias to its stem only when the number follows it Mehmet Fide
2026-10-20 10:16 ` [PATCH v7 2/9] usb: ehci-vf: take the controller index from the device tree Mehmet Fide
2026-10-20 10:16 ` [PATCH v7 3/9] usb: ehci-vf: remove the code path for a build without DM_USB Mehmet Fide
2026-10-20 10:16 ` [PATCH v7 4/9] usb: ehci-vf: drop the empty bind hook Mehmet Fide
2026-10-20 10:16 ` [PATCH v7 5/9] dm: core: add ofnode_get_alias_seq() Mehmet Fide
2026-10-20 10:16 ` [PATCH v7 6/9] usb: ehci-vf: use usb_get_dr_mode() Mehmet Fide
2026-10-21  0:09   ` Marek Vasut
2026-10-21 11:59     ` Mehmet Fide
2026-10-21 12:07       ` Marek Vasut
2026-10-21 12:21         ` Mehmet Fide
2026-10-21 13:17           ` Marek Vasut
2026-10-21 18:41             ` Mehmet Fide
2026-10-21 18:56               ` Marek Vasut
2026-10-20 10:16 ` [PATCH v7 7/9] usb: ehci-vf: request the ID detect gpio through the device Mehmet Fide
2026-10-21  0:10   ` Marek Vasut
2026-10-20 10:16 ` [PATCH v7 8/9] usb: ehci-vf: take the register bases from the device tree Mehmet Fide
2026-10-21  0:13   ` Marek Vasut
2026-10-20 10:16 ` [PATCH v7 9/9] usb: ehci-vf: enable the vbus supply of the port Mehmet Fide
2026-10-21  0:13   ` Marek Vasut
2026-10-21 11:59     ` Mehmet Fide

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.