* [PATCH v3 1/9] dt-bindings: phy: Document ST STM32MP25 USB2-FEMTO PHY
2026-08-22 7:46 [PATCH v3 0/9] arm64: dts: phy: st: usb: Add STM32MP2 USB support Marek Vasut
@ 2026-08-22 7:46 ` Marek Vasut
2026-08-22 7:55 ` sashiko-bot
2026-08-22 7:46 ` [PATCH v3 2/9] phy: stm32: Add support for " Marek Vasut
` (7 subsequent siblings)
8 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2026-08-22 7:46 UTC (permalink / raw)
To: linux-usb
Cc: fabrice.gasnier, Pankaj Dev, Rahul Kumar, Clément Le Goffic,
Marek Vasut, Alexandre Torgue, Christian Bruel, Conor Dooley,
Greg Kroah-Hartman, Krzysztof Kozlowski, Maxime Coquelin,
Neil Armstrong, Rob Herring, Rosen Penev, Thinh Nguyen,
Vinod Koul, devicetree, kernel, linux-arm-kernel, linux-kernel,
linux-phy, linux-stm32
From: Pankaj Dev <pankaj.dev@st.com>
Document USB2 PHY for STM32MP25 USB2 controllers, which includes the
USB2.0 host-only controller and USB 2.0 part of the DWC3 controller.
Two such PHYs in total are present in STM32MP25 SoC, they both are
slightly different, therefore they use different compatible string
to discern them.
Signed-off-by: Pankaj Dev <pankaj.dev@st.com>
Co-developed-by: Rahul Kumar <rahul.kumar05@st.com>
Signed-off-by: Rahul Kumar <rahul.kumar05@st.com>
Co-developed-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Co-developed-by: Clément Le Goffic <clement.legoffic@foss.st.com>
Signed-off-by: Clément Le Goffic <clement.legoffic@foss.st.com>
Co-developed-by: Marek Vasut <marex@nabladev.com>
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Christian Bruel <christian.bruel@foss.st.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Pankaj Dev <pankaj.dev@st.com>
Cc: Rahul Kumar <rahul.kumar05@st.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Rosen Penev <rosenp@gmail.com>
Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: kernel@dh-electronics.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-usb@vger.kernel.org
---
V2: - Fix up Sob/Cdb lines
- Fix up compatible string in example
- Use additionalProperties: false
- Expand description:
- Use clock-cells = <1> to discern OSC and future PLL clock from the PHY
V3: - Move clock-cells next to PHY cells
- Fix the bindings
- Fix up Sob/Cdb lines further
---
.../bindings/phy/st,stm32-usb2phy.yaml | 67 +++++++++++++++++++
1 file changed, 67 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/st,stm32-usb2phy.yaml
diff --git a/Documentation/devicetree/bindings/phy/st,stm32-usb2phy.yaml b/Documentation/devicetree/bindings/phy/st,stm32-usb2phy.yaml
new file mode 100644
index 0000000000000..cc5044790beea
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/st,stm32-usb2phy.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/st,stm32-usb2phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32 MPU High-Speed USB PHY
+
+description:
+ USB2 PHY block in STM32 is attached to USB 2.0 Host controller and
+ USB 2.0 side of DWC3 DRD controller, and provides the USB LS/FS/HS
+ connectivity. Both PHYs are the FEMTO-PHY, but their configuration
+ bits in the system control register are different for each variant.
+
+maintainers:
+ - Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+ - Marek Vasut <marex@nabladev.com>
+ - Pankaj Dev <pankaj.dev@st.com>
+
+properties:
+ compatible:
+ enum:
+ - st,stm32mp25-usb2phy1
+ - st,stm32mp25-usb2phy2
+
+ "#clock-cells":
+ const: 1
+
+ "#phy-cells":
+ const: 0
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+
+ vdd33-supply:
+ description: Phandle to regulator providing 3V3 power supply to the USB2 HS PHY
+
+required:
+ - compatible
+ - "#clock-cells"
+ - "#phy-cells"
+ - clocks
+ - resets
+ - vdd33-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/st,stm32mp25-rcc.h>
+ #include <dt-bindings/reset/st,stm32mp25-rcc.h>
+
+ usb-phy@2400 {
+ compatible = "st,stm32mp25-usb2phy1";
+ reg = <0x2400 0x24>;
+ #phy-cells = <0>;
+ #clock-cells = <1>;
+ clocks = <&rcc CK_KER_USB2PHY1>;
+ resets = <&rcc USB2PHY1_R>;
+ vdd33-supply = <&vdd33usb>;
+ };
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v3 1/9] dt-bindings: phy: Document ST STM32MP25 USB2-FEMTO PHY
2026-08-22 7:46 ` [PATCH v3 1/9] dt-bindings: phy: Document ST STM32MP25 USB2-FEMTO PHY Marek Vasut
@ 2026-08-22 7:55 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-08-22 7:55 UTC (permalink / raw)
To: Marek Vasut
Cc: vkoul, neil.armstrong, olteanv, robh, conor+dt, linux-phy,
devicetree
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Low] The `reg` property is defined in the schema and used in the example but is missing from the `required` list.
- [Low] The example node name 'usb-phy@2400' violates the generic PHY schema pattern.
- [Low] The '#clock-cells' property lacks documentation for the clock indices.
--
--- Patch [1]: [PATCH v3 1/9] dt-bindings: phy: Document ST STM32MP25 USB2-FEMTO PHY ---
commit fee849432713aad415e73ed872e6de622206bee8
Author: Pankaj Dev <pankaj.dev@st.com>
dt-bindings: phy: Document ST STM32MP25 USB2-FEMTO PHY
This commit documents the USB2 phy for STM32MP25 USB2 controllers. It introduces
bindings for two slightly different phys present in the STM32MP25 SoC using
separate compatible strings.
> diff --git a/Documentation/devicetree/bindings/phy/st,stm32-usb2phy.yaml b/Documentation/devicetree/bindings/phy/st,stm32-usb2phy.yaml
> new file mode 100644
> index 0000000000000..cc5044790beea
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/st,stm32-usb2phy.yaml
> @@ -0,0 +1,67 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
[ ... ]
> +properties:
> + compatible:
> + enum:
> + - st,stm32mp25-usb2phy1
> + - st,stm32mp25-usb2phy2
> +
> + "#clock-cells":
> + const: 1
> +
[Severity: Low]
This sets #clock-cells to 1, meaning consumers will need to pass an index,
but there doesn't appear to be any documentation of the valid indices (e.g.,
0 for PLL, 1 for CMN) in the binding or a dt-bindings header file.
Could this be updated to document what index corresponds to which clock so
device tree authors aren't forced to rely on undocumented magic numbers?
> + "#phy-cells":
> + const: 0
> +
> + reg:
> + maxItems: 1
[ ... ]
> +required:
> + - compatible
> + - "#clock-cells"
> + - "#phy-cells"
> + - clocks
> + - resets
> + - vdd33-supply
[Severity: Low]
The reg property is defined in the schema and used in the example below,
but it is missing from this list.
If it is omitted here, device tree nodes without a register offset can
silently pass schema validation, even though the driver will fail to probe.
Should the reg property be included in this required list?
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/st,stm32mp25-rcc.h>
> + #include <dt-bindings/reset/st,stm32mp25-rcc.h>
> +
> + usb-phy@2400 {
[Severity: Low]
Generic phy schema patterns in dtschema restrict node names for phy
providers to match the regular expression ^phy(@.*)?$.
Will this node name trigger warnings when validating the example during a
dt_binding_check?
> + compatible = "st,stm32mp25-usb2phy1";
> + reg = <0x2400 0x24>;
> + #phy-cells = <0>;
> + #clock-cells = <1>;
> + clocks = <&rcc CK_KER_USB2PHY1>;
> + resets = <&rcc USB2PHY1_R>;
> + vdd33-supply = <&vdd33usb>;
> + };
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260822074816.548662-1-marex@nabladev.com?part=1
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 2/9] phy: stm32: Add support for ST STM32MP25 USB2-FEMTO PHY
2026-08-22 7:46 [PATCH v3 0/9] arm64: dts: phy: st: usb: Add STM32MP2 USB support Marek Vasut
2026-08-22 7:46 ` [PATCH v3 1/9] dt-bindings: phy: Document ST STM32MP25 USB2-FEMTO PHY Marek Vasut
@ 2026-08-22 7:46 ` Marek Vasut
2026-08-22 7:58 ` sashiko-bot
2026-08-24 13:17 ` Fabrice Gasnier
2026-08-22 7:46 ` [PATCH v3 3/9] dt-bindings: usb: generic-ehci: Document access-controllers property Marek Vasut
` (6 subsequent siblings)
8 siblings, 2 replies; 21+ messages in thread
From: Marek Vasut @ 2026-08-22 7:46 UTC (permalink / raw)
To: linux-usb
Cc: fabrice.gasnier, Pankaj Dev, Rahul Kumar, Christian Bruel,
Marek Vasut, Alexandre Torgue, Conor Dooley, Greg Kroah-Hartman,
Krzysztof Kozlowski, Maxime Coquelin, Neil Armstrong, Rob Herring,
Rosen Penev, Thinh Nguyen, Vinod Koul, devicetree, kernel,
linux-arm-kernel, linux-kernel, linux-phy, linux-stm32
From: Pankaj Dev <pankaj.dev@st.com>
Add USB2 PHY driver for STM32MP25 USB2 controllers, which includes the
USB2.0 host-only controller and USB 2.0 part of the DWC3 controller.
Two such PHYs in total are present in STM32MP25 SoC, they both are
slightly different, therefore they use different compatible string
to discern them.
Signed-off-by: Pankaj Dev <pankaj.dev@st.com>
Co-developed-by: Rahul Kumar <rahul.kumar05@st.com>
Signed-off-by: Rahul Kumar <rahul.kumar05@st.com>
Co-developed-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Co-developed-by: Christian Bruel <christian.bruel@foss.st.com>
Signed-off-by: Christian Bruel <christian.bruel@foss.st.com>
Co-developed-by: Marek Vasut <marex@nabladev.com>
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Christian Bruel <christian.bruel@foss.st.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Pankaj Dev <pankaj.dev@st.com>
Cc: Rahul Kumar <rahul.kumar05@st.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Rosen Penev <rosenp@gmail.com>
Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: kernel@dh-electronics.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-usb@vger.kernel.org
---
V2: - Fix up Sob/Cdb lines
- Operate PHY as a syscon subnode
V3: - Update copyright years
- Register two sets of clock, one 480 MHz PLL and one CMN
- Split PHY ops per PHY, since the PHY2 does not have set mode ops
- Fix up Sob/Cdb lines further
---
drivers/phy/st/Kconfig | 10 +
drivers/phy/st/Makefile | 1 +
drivers/phy/st/phy-stm32-usb2phy.c | 406 +++++++++++++++++++++++++++++
3 files changed, 417 insertions(+)
create mode 100644 drivers/phy/st/phy-stm32-usb2phy.c
diff --git a/drivers/phy/st/Kconfig b/drivers/phy/st/Kconfig
index 49206185e5633..2835bb67bca9e 100644
--- a/drivers/phy/st/Kconfig
+++ b/drivers/phy/st/Kconfig
@@ -58,3 +58,13 @@ config PHY_STM32_USBPHYC
used by an HS USB Host controller, and the second one is shared
between an HS USB OTG controller and an HS USB Host controller,
selected by a USB switch.
+
+config PHY_STM32_USB2PHY
+ tristate "STMicroelectronics STM32MP25 USB2.0 PHY Controller driver"
+ depends on ARCH_STM32 || COMPILE_TEST
+ depends on COMMON_CLK
+ select GENERIC_PHY
+ help
+ Enable this to support the High-Speed USB 2.0 transceivers that are
+ part of the STMicroelectronics STM32MP25 SoCs. The PHY itself is a
+ Synopsys FEMTO-PHY.
diff --git a/drivers/phy/st/Makefile b/drivers/phy/st/Makefile
index cb80e954ea9f0..4945df5ed78a8 100644
--- a/drivers/phy/st/Makefile
+++ b/drivers/phy/st/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o
obj-$(CONFIG_PHY_STM32_COMBOPHY) += phy-stm32-combophy.o
obj-$(CONFIG_PHY_STM32_USBPHYC) += phy-stm32-usbphyc.o
+obj-$(CONFIG_PHY_STM32_USB2PHY) += phy-stm32-usb2phy.o
diff --git a/drivers/phy/st/phy-stm32-usb2phy.c b/drivers/phy/st/phy-stm32-usb2phy.c
new file mode 100644
index 0000000000000..8c68b2d208d73
--- /dev/null
+++ b/drivers/phy/st/phy-stm32-usb2phy.c
@@ -0,0 +1,406 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * STMicroelectronics STM32 USB2 PHY Controller driver
+ * Currently Only supported for STM32MP25
+ *
+ * Copyright (C) 2022-2026 STMicroelectronics
+ * Author(s): Pankaj Dev <pankaj.dev@st.com>.
+ */
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/usb/role.h>
+#include <linux/mfd/syscon.h>
+
+#define SYSCFG_USB2PHY2CR_USB2PHY2CMN BIT(2)
+#define SYSCFG_USB2PHY2CR_VBUSVALID BIT(4)
+#define SYSCFG_USB2PHY2CR_VBUSVLDEXTSEL BIT(5)
+#define SYSCFG_USB2PHY2CR_VBUSVLDEXT BIT(6)
+
+#define USBH_NUM_CLK 2
+
+struct stm32_usb2phy {
+ struct phy *phy;
+ struct regmap *regmap;
+ struct device *dev;
+ struct reset_control *rstc;
+ struct clk *phyref;
+ struct regulator *vdd33;
+ const struct stm32mp2_usb2phy_hw_data *hw_data;
+ atomic_t en_refcnt;
+ enum phy_mode mode;
+ u32 cr_offset;
+ bool is_init;
+ struct clk_hw clkpll_hw;
+ struct clk_hw clkcmn_hw;
+ /* Must be last */
+ struct clk_hw_onecell_data onecell;
+};
+
+struct stm32mp2_usb2phy_hw_data {
+ u32 phyrefsel_mask;
+ const struct phy_ops *phy_ops;
+};
+
+static int stm32_usb2phy_enable(struct stm32_usb2phy *phy_dev)
+{
+ const struct stm32mp2_usb2phy_hw_data *phy_data = phy_dev->hw_data;
+ unsigned int refsel;
+ unsigned long rate;
+ int ret;
+
+ /* Check if a phy is already init or clkpll in use */
+ if (atomic_inc_return(&phy_dev->en_refcnt) > 1)
+ return 0;
+
+ rate = clk_get_rate(phy_dev->phyref);
+ if (rate == 19200000)
+ refsel = 0;
+ else if (rate == 20000000)
+ refsel = 1;
+ else if (rate == 24000000)
+ refsel = 2;
+ else
+ return -EINVAL;
+
+ ret = regmap_update_bits(phy_dev->regmap,
+ phy_dev->cr_offset,
+ phy_data->phyrefsel_mask,
+ field_prep(phy_data->phyrefsel_mask, refsel));
+ if (ret)
+ return ret;
+
+ ret = regulator_enable(phy_dev->vdd33);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(phy_dev->phyref);
+ if (ret)
+ goto error_regdis;
+
+ ret = reset_control_deassert(phy_dev->rstc);
+ if (ret)
+ goto error_clkdis;
+
+ return 0;
+
+error_clkdis:
+ clk_disable_unprepare(phy_dev->phyref);
+error_regdis:
+ regulator_disable(phy_dev->vdd33);
+
+ return ret;
+}
+
+static int stm32_usb2phy_disable(struct stm32_usb2phy *phy_dev)
+{
+ int ret;
+
+ /* Check if a phy is still init or clkpll in use */
+ if (atomic_dec_return(&phy_dev->en_refcnt) > 0)
+ return 0;
+
+ ret = reset_control_assert(phy_dev->rstc);
+ if (ret)
+ return ret;
+
+ clk_disable_unprepare(phy_dev->phyref);
+
+ return regulator_disable(phy_dev->vdd33);
+}
+
+static int stm32_usb2phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+ struct stm32_usb2phy *phy_dev = phy_get_drvdata(phy);
+ u32 mask = SYSCFG_USB2PHY2CR_USB2PHY2CMN |
+ SYSCFG_USB2PHY2CR_VBUSVALID |
+ SYSCFG_USB2PHY2CR_VBUSVLDEXT;
+ u32 val = 0;
+ int ret;
+
+ if (mode == PHY_MODE_USB_HOST) {
+ if (submode != USB_ROLE_NONE)
+ val = SYSCFG_USB2PHY2CR_VBUSVALID;
+ } else if (mode == PHY_MODE_USB_DEVICE) {
+ val = SYSCFG_USB2PHY2CR_USB2PHY2CMN |
+ SYSCFG_USB2PHY2CR_VBUSVLDEXTSEL;
+ if (submode != USB_ROLE_NONE)
+ val |= SYSCFG_USB2PHY2CR_VBUSVLDEXT;
+ mask |= SYSCFG_USB2PHY2CR_VBUSVLDEXTSEL;
+ } else {
+ return -EINVAL;
+ }
+
+ ret = regmap_update_bits(phy_dev->regmap, phy_dev->cr_offset, mask, val);
+ if (ret)
+ return ret;
+
+ phy_dev->mode = mode;
+
+ return 0;
+}
+
+static int stm32_usb2phy1_init(struct phy *phy)
+{
+ struct stm32_usb2phy *phy_dev = phy_get_drvdata(phy);
+ int ret;
+
+ ret = stm32_usb2phy_enable(phy_dev);
+ if (ret)
+ return ret;
+
+ phy_dev->is_init = true;
+
+ return 0;
+}
+
+static int stm32_usb2phy2_init(struct phy *phy)
+{
+ struct stm32_usb2phy *phy_dev = phy_get_drvdata(phy);
+ int ret;
+
+ ret = stm32_usb2phy_enable(phy_dev);
+ if (ret)
+ return ret;
+
+ if (phy_dev->mode != PHY_MODE_INVALID) {
+ ret = stm32_usb2phy_set_mode(phy, phy_dev->mode, USB_ROLE_NONE);
+ if (ret) {
+ stm32_usb2phy_disable(phy_dev);
+ return ret;
+ }
+ }
+
+ phy_dev->is_init = true;
+
+ return 0;
+}
+
+static int stm32_usb2phy_exit(struct phy *phy)
+{
+ struct stm32_usb2phy *phy_dev = phy_get_drvdata(phy);
+ int ret;
+
+ ret = stm32_usb2phy_disable(phy_dev);
+ if (ret)
+ return ret;
+
+ phy_dev->is_init = false;
+
+ return 0;
+}
+
+static const struct phy_ops stm32_usb2phy1_data = {
+ .init = stm32_usb2phy1_init,
+ .exit = stm32_usb2phy_exit,
+ .owner = THIS_MODULE,
+};
+
+static const struct phy_ops stm32_usb2phy2_data = {
+ .init = stm32_usb2phy2_init,
+ .exit = stm32_usb2phy_exit,
+ .set_mode = stm32_usb2phy_set_mode,
+ .owner = THIS_MODULE,
+};
+
+static int stm32_usb2phy_clkpll_prepare(struct clk_hw *hw)
+{
+ struct stm32_usb2phy *phy_dev = container_of(hw, struct stm32_usb2phy,
+ clkpll_hw);
+
+ return stm32_usb2phy_enable(phy_dev);
+}
+
+static void stm32_usb2phy_clkpll_unprepare(struct clk_hw *hw)
+{
+ struct stm32_usb2phy *phy_dev = container_of(hw, struct stm32_usb2phy,
+ clkpll_hw);
+
+ stm32_usb2phy_disable(phy_dev);
+}
+
+static unsigned long stm32_usb2phy_clkpll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ return 480000000;
+}
+
+static const struct clk_ops stm32_usb2phy_clkpll_ops = {
+ .prepare = stm32_usb2phy_clkpll_prepare,
+ .unprepare = stm32_usb2phy_clkpll_unprepare,
+ .recalc_rate = stm32_usb2phy_clkpll_recalc_rate,
+};
+
+static int stm32_usb2phy_clkcmn_prepare(struct clk_hw *hw)
+{
+ struct stm32_usb2phy *phy_dev = container_of(hw, struct stm32_usb2phy,
+ clkcmn_hw);
+
+ return regmap_clear_bits(phy_dev->regmap, phy_dev->cr_offset,
+ SYSCFG_USB2PHY2CR_USB2PHY2CMN);
+}
+
+static void stm32_usb2phy_clkcmn_unprepare(struct clk_hw *hw)
+{
+ struct stm32_usb2phy *phy_dev = container_of(hw, struct stm32_usb2phy,
+ clkcmn_hw);
+
+ regmap_set_bits(phy_dev->regmap, phy_dev->cr_offset,
+ SYSCFG_USB2PHY2CR_USB2PHY2CMN);
+}
+
+static const struct clk_ops stm32_usb2phy_clkcmn_ops = {
+ .prepare = stm32_usb2phy_clkcmn_prepare,
+ .unprepare = stm32_usb2phy_clkcmn_unprepare,
+};
+
+static int stm32_usb2phy_probe(struct platform_device *pdev)
+{
+ struct phy_provider *phy_provider;
+ struct device *dev = &pdev->dev;
+ struct stm32_usb2phy *phy_dev;
+ char *pllname, *cmnname;
+ const __be32 *offset;
+ struct phy *phy;
+ int ret;
+
+ phy_dev = devm_kzalloc(dev, struct_size(phy_dev, onecell.hws, USBH_NUM_CLK), GFP_KERNEL);
+ if (!phy_dev)
+ return -ENOMEM;
+
+ phy_dev->dev = dev;
+ dev_set_drvdata(dev, phy_dev);
+
+ phy_dev->rstc = devm_reset_control_get(dev, NULL);
+ if (IS_ERR(phy_dev->rstc))
+ return dev_err_probe(dev, PTR_ERR(phy_dev->rstc), "Failed to get USB2PHY reset\n");
+
+ phy_dev->phyref = devm_clk_get(dev, NULL);
+ if (IS_ERR(phy_dev->phyref))
+ return dev_err_probe(dev, PTR_ERR(phy_dev->phyref), "Failed to get phyref clk\n");
+
+ phy_dev->vdd33 = devm_regulator_get_optional(dev, "vdd33");
+ if (IS_ERR(phy_dev->vdd33))
+ return dev_err_probe(dev, PTR_ERR(phy_dev->vdd33), "Failed to get vdd3v3 supply\n");
+
+ phy_dev->regmap = syscon_node_to_regmap(dev->of_node->parent);
+ if (IS_ERR(phy_dev->regmap))
+ return dev_err_probe(dev, PTR_ERR(phy_dev->regmap), "Failed to get regmap\n");
+
+ offset = of_get_address(dev->of_node, 0, NULL, NULL);
+ if (!offset)
+ return dev_err_probe(dev, -EINVAL, "Failed to get regmap offset\n");
+
+ phy_dev->cr_offset = be32_to_cpu(*offset);
+
+ phy_dev->hw_data = device_get_match_data(dev);
+
+ phy = devm_phy_create(dev, NULL, phy_dev->hw_data->phy_ops);
+ if (IS_ERR(phy))
+ return dev_err_probe(dev, PTR_ERR(phy), "Failed to create PHY\n");
+
+ phy_dev->phy = phy;
+ phy_set_drvdata(phy, phy_dev);
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ if (IS_ERR(phy_provider))
+ return PTR_ERR(phy_provider);
+
+ pllname = devm_kasprintf(dev, GFP_KERNEL, "clk_%s_48m",
+ of_node_full_name(dev->of_node));
+ if (!pllname)
+ return -ENOMEM;
+
+ cmnname = devm_kasprintf(dev, GFP_KERNEL, "clk_%s_cmn",
+ of_node_full_name(dev->of_node));
+ if (!cmnname)
+ return -ENOMEM;
+
+ phy_dev->onecell.num = USBH_NUM_CLK;
+ phy_dev->onecell.hws[0] = &phy_dev->clkpll_hw;
+ phy_dev->onecell.hws[1] = &phy_dev->clkcmn_hw;
+
+ phy_dev->clkpll_hw.init = CLK_HW_INIT_NO_PARENT(pllname, &stm32_usb2phy_clkpll_ops, 0);
+ ret = devm_clk_hw_register(phy_dev->dev, &phy_dev->clkpll_hw);
+ if (ret)
+ return dev_err_probe(phy_dev->dev, ret, "Failed to register PLL clock\n");
+
+ phy_dev->clkcmn_hw.init = CLK_HW_INIT_HW(cmnname, &phy_dev->clkpll_hw,
+ &stm32_usb2phy_clkcmn_ops, 0);
+ ret = devm_clk_hw_register(phy_dev->dev, &phy_dev->clkcmn_hw);
+ if (ret)
+ return dev_err_probe(phy_dev->dev, ret, "Failed to register CMN clock\n");
+
+ ret = devm_of_clk_add_hw_provider(phy_dev->dev, of_clk_hw_onecell_get, &phy_dev->onecell);
+ if (ret)
+ return dev_err_probe(phy_dev->dev, ret, "Failed to add clock provider\n");
+
+ return 0;
+}
+
+static int stm32_usb2phy_suspend(struct device *dev)
+{
+ struct stm32_usb2phy *phy_dev = dev_get_drvdata(dev);
+
+ if (phy_dev->is_init)
+ return stm32_usb2phy_disable(phy_dev);
+
+ return 0;
+}
+
+static int stm32_usb2phy_resume(struct device *dev)
+{
+ struct stm32_usb2phy *phy_dev = dev_get_drvdata(dev);
+
+ if (phy_dev->is_init)
+ return stm32_usb2phy_enable(phy_dev);
+
+ return 0;
+}
+
+/* STM32MP25xx USB 2.0 PHY attached to USB 2.0 Host controller */
+static const struct stm32mp2_usb2phy_hw_data stm32mp25_usb2phy1_hwdata = {
+ .phyrefsel_mask = GENMASK(6, 4),
+ .phy_ops = &stm32_usb2phy1_data,
+};
+
+/* STM32MP25xx USB 2.0 PHY attached to USB 2.0 part of DWC3 controller */
+static const struct stm32mp2_usb2phy_hw_data stm32mp25_usb2phy2_hwdata = {
+ .phyrefsel_mask = GENMASK(14, 12),
+ .phy_ops = &stm32_usb2phy2_data,
+};
+
+static const struct of_device_id stm32_usb2phy_of_match[] = {
+ { .compatible = "st,stm32mp25-usb2phy1", .data = &stm32mp25_usb2phy1_hwdata },
+ { .compatible = "st,stm32mp25-usb2phy2", .data = &stm32mp25_usb2phy2_hwdata },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, stm32_usb2phy_of_match);
+
+static DEFINE_SIMPLE_DEV_PM_OPS(stm32_usb2phy_pm_ops,
+ stm32_usb2phy_suspend, stm32_usb2phy_resume);
+
+static struct platform_driver stm32_usb2phy_driver = {
+ .probe = stm32_usb2phy_probe,
+ .driver = {
+ .name = "stm32-usb2phy",
+ .of_match_table = stm32_usb2phy_of_match,
+ .pm = pm_sleep_ptr(&stm32_usb2phy_pm_ops)
+ }
+};
+
+module_platform_driver(stm32_usb2phy_driver);
+
+MODULE_AUTHOR("Pankaj Dev <pankaj.dev@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics Generic USB2PHY driver for stm32");
+MODULE_LICENSE("GPL");
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v3 2/9] phy: stm32: Add support for ST STM32MP25 USB2-FEMTO PHY
2026-08-22 7:46 ` [PATCH v3 2/9] phy: stm32: Add support for " Marek Vasut
@ 2026-08-22 7:58 ` sashiko-bot
2026-08-24 13:17 ` Fabrice Gasnier
1 sibling, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-08-22 7:58 UTC (permalink / raw)
To: Marek Vasut
Cc: neil.armstrong, conor+dt, vkoul, olteanv, linux-phy, robh,
devicetree
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] Error paths in `stm32_usb2phy_enable` and `stm32_usb2phy_disable` fail to correctly rollback the `en_refcnt` atomic counter, leading to permanent state lockup or leaked resources.
- [High] Lack of serialization in hardware initialization allows concurrent callers to bypass initialization and access unready hardware.
- [High] `stm32_usb2phy_set_mode()` fails to clear `SYSCFG_USB2PHY2CR_VBUSVLDEXTSEL` when switching from device mode to host mode.
- [High] The driver inappropriately treats an optional regulator as mandatory by unconditionally failing probe on `-ENODEV`.
- [Medium] `stm32_usb2phy2_init` hardcodes `USB_ROLE_NONE`, erasing submode state across re-init cycles.
- [Medium] Uncoordinated access to the `SYSCFG_USB2PHY2CR_USB2PHY2CMN` bit between the PHY mode setting and the Clock prepare/unprepare operations.
--
--- Patch [2]: [PATCH v3 2/9] phy: stm32: Add support for ST STM32MP25 USB2-FEMTO PHY ---
commit 6743b66f90992ce83291ec2073d75b9d6849c462
Author: Pankaj Dev <pankaj.dev@st.com>
Subject: phy: stm32: Add support for ST STM32MP25 USB2-FEMTO PHY
This commit adds the USB2 PHY driver for STM32MP25 USB2 controllers. It
supports the USB 2.0 host-only controller and the USB 2.0 part of the DWC3
controller.
> diff --git a/drivers/phy/st/phy-stm32-usb2phy.c b/drivers/phy/st/phy-stm32-usb2phy.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/phy/st/phy-stm32-usb2phy.c
[ ... ]
> +static int stm32_usb2phy_enable(struct stm32_usb2phy *phy_dev)
> +{
> + const struct stm32mp2_usb2phy_hw_data *phy_data = phy_dev->hw_data;
> + unsigned int refsel;
> + unsigned long rate;
> + int ret;
> +
> + /* Check if a phy is already init or clkpll in use */
> + if (atomic_inc_return(&phy_dev->en_refcnt) > 1)
> + return 0;
[Severity: High]
Can concurrent callers bypass hardware initialization here? If two threads
call stm32_usb2phy_enable() at the same time, it seems the second caller
will observe the incremented counter and return immediately, while the first
thread is still executing the setup sequence. Would it be safer to use a
driver-level mutex to serialize initialization instead of an atomic check?
> +
> + rate = clk_get_rate(phy_dev->phyref);
> + if (rate == 19200000)
> + refsel = 0;
> + else if (rate == 20000000)
> + refsel = 1;
> + else if (rate == 24000000)
> + refsel = 2;
> + else
> + return -EINVAL;
[Severity: High]
If stm32_usb2phy_enable() returns -EINVAL for an unsupported clock rate,
does en_refcnt remain incremented? It looks like subsequent calls might see
an inflated count and return success without doing any hardware initialization.
> +
> + ret = regmap_update_bits(phy_dev->regmap,
[ ... ]
> +static int stm32_usb2phy_disable(struct stm32_usb2phy *phy_dev)
> +{
> + int ret;
> +
> + /* Check if a phy is still init or clkpll in use */
> + if (atomic_dec_return(&phy_dev->en_refcnt) > 0)
> + return 0;
> +
> + ret = reset_control_assert(phy_dev->rstc);
> + if (ret)
> + return ret;
[Severity: High]
If reset_control_assert() fails, does the early return leave en_refcnt
decremented while resources are still enabled? This might lead to a state
mismatch and resource leaks if the hardware is out of sync with the reference
count.
> +
> + clk_disable_unprepare(phy_dev->phyref);
> +
> + return regulator_disable(phy_dev->vdd33);
> +}
> +
> +static int stm32_usb2phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
> +{
> + struct stm32_usb2phy *phy_dev = phy_get_drvdata(phy);
> + u32 mask = SYSCFG_USB2PHY2CR_USB2PHY2CMN |
> + SYSCFG_USB2PHY2CR_VBUSVALID |
> + SYSCFG_USB2PHY2CR_VBUSVLDEXT;
[Severity: High]
When switching back to host mode, is the SYSCFG_USB2PHY2CR_VBUSVLDEXTSEL bit
left set? It appears omitted from this default mask.
If it was set during a switch to PHY_MODE_USB_DEVICE, it looks like it won't
be cleared when returning to PHY_MODE_USB_HOST, which might leave the
hardware multiplexer stuck on external VBUS sensing.
> + u32 val = 0;
> + int ret;
> +
> + if (mode == PHY_MODE_USB_HOST) {
> + if (submode != USB_ROLE_NONE)
> + val = SYSCFG_USB2PHY2CR_VBUSVALID;
> + } else if (mode == PHY_MODE_USB_DEVICE) {
> + val = SYSCFG_USB2PHY2CR_USB2PHY2CMN |
> + SYSCFG_USB2PHY2CR_VBUSVLDEXTSEL;
[Severity: Medium]
Can toggling the CMN clock corrupt the mode configuration? The PHY framework
sets the SYSCFG_USB2PHY2CR_USB2PHY2CMN bit here, but the clock framework
clears this exact same bit in stm32_usb2phy_clkcmn_prepare(). This
uncoordinated access might step on the PHY's expected state.
> + if (submode != USB_ROLE_NONE)
> + val |= SYSCFG_USB2PHY2CR_VBUSVLDEXT;
> + mask |= SYSCFG_USB2PHY2CR_VBUSVLDEXTSEL;
> + } else {
> + return -EINVAL;
> + }
[ ... ]
> +static int stm32_usb2phy2_init(struct phy *phy)
> +{
> + struct stm32_usb2phy *phy_dev = phy_get_drvdata(phy);
> + int ret;
> +
> + ret = stm32_usb2phy_enable(phy_dev);
> + if (ret)
> + return ret;
> +
> + if (phy_dev->mode != PHY_MODE_INVALID) {
> + ret = stm32_usb2phy_set_mode(phy, phy_dev->mode, USB_ROLE_NONE);
[Severity: Medium]
Does hardcoding USB_ROLE_NONE erase the previously configured submode state?
If the PHY was previously configured with a valid submode, calling phy_init()
again might explicitly clear the VBUSVALID and VBUSVLDEXT bits, leading to
a silent loss of VBUS detection state.
> + if (ret) {
> + stm32_usb2phy_disable(phy_dev);
> + return ret;
> + }
> + }
> +
> + phy_dev->is_init = true;
> +
> + return 0;
> +}
[ ... ]
> +static int stm32_usb2phy_probe(struct platform_device *pdev)
> +{
> + struct phy_provider *phy_provider;
> + struct device *dev = &pdev->dev;
> + struct stm32_usb2phy *phy_dev;
> + char *pllname, *cmnname;
> + const __be32 *offset;
> + struct phy *phy;
> + int ret;
[ ... ]
> + phy_dev->phyref = devm_clk_get(dev, NULL);
> + if (IS_ERR(phy_dev->phyref))
> + return dev_err_probe(dev, PTR_ERR(phy_dev->phyref), "Failed to get phyref clk\n");
> +
> + phy_dev->vdd33 = devm_regulator_get_optional(dev, "vdd33");
> + if (IS_ERR(phy_dev->vdd33))
> + return dev_err_probe(dev, PTR_ERR(phy_dev->vdd33), "Failed to get vdd3v3 supply\n");
[Severity: High]
Does returning PTR_ERR() unconditionally here defeat the purpose of using
an optional regulator? devm_regulator_get_optional() returns -ENODEV if the
regulator is absent in the device tree, which would cause the probe to fail
unconditionally on platforms without it.
> +
> + phy_dev->regmap = syscon_node_to_regmap(dev->of_node->parent);
> + if (IS_ERR(phy_dev->regmap))
> + return dev_err_probe(dev, PTR_ERR(phy_dev->regmap), "Failed to get regmap\n");
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260822074816.548662-1-marex@nabladev.com?part=2
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v3 2/9] phy: stm32: Add support for ST STM32MP25 USB2-FEMTO PHY
2026-08-22 7:46 ` [PATCH v3 2/9] phy: stm32: Add support for " Marek Vasut
2026-08-22 7:58 ` sashiko-bot
@ 2026-08-24 13:17 ` Fabrice Gasnier
2026-08-24 14:53 ` Marek Vasut
1 sibling, 1 reply; 21+ messages in thread
From: Fabrice Gasnier @ 2026-08-24 13:17 UTC (permalink / raw)
To: Marek Vasut, linux-usb
Cc: Pankaj Dev, Rahul Kumar, Christian Bruel, Alexandre Torgue,
Conor Dooley, Greg Kroah-Hartman, Krzysztof Kozlowski,
Maxime Coquelin, Neil Armstrong, Rob Herring, Rosen Penev,
Thinh Nguyen, Vinod Koul, devicetree, kernel, linux-arm-kernel,
linux-kernel, linux-phy, linux-stm32
On 8/22/26 09:46, Marek Vasut wrote:
> From: Pankaj Dev <pankaj.dev@st.com>
>
> Add USB2 PHY driver for STM32MP25 USB2 controllers, which includes the
> USB2.0 host-only controller and USB 2.0 part of the DWC3 controller.
> Two such PHYs in total are present in STM32MP25 SoC, they both are
> slightly different, therefore they use different compatible string
> to discern them.
>
> Signed-off-by: Pankaj Dev <pankaj.dev@st.com>
> Co-developed-by: Rahul Kumar <rahul.kumar05@st.com>
> Signed-off-by: Rahul Kumar <rahul.kumar05@st.com>
> Co-developed-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
> Co-developed-by: Christian Bruel <christian.bruel@foss.st.com>
> Signed-off-by: Christian Bruel <christian.bruel@foss.st.com>
> Co-developed-by: Marek Vasut <marex@nabladev.com>
> Signed-off-by: Marek Vasut <marex@nabladev.com>
> ---
> Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
> Cc: Christian Bruel <christian.bruel@foss.st.com>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> Cc: Neil Armstrong <neil.armstrong@linaro.org>
> Cc: Pankaj Dev <pankaj.dev@st.com>
> Cc: Rahul Kumar <rahul.kumar05@st.com>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Rosen Penev <rosenp@gmail.com>
> Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
> Cc: Vinod Koul <vkoul@kernel.org>
> Cc: devicetree@vger.kernel.org
> Cc: kernel@dh-electronics.com
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-phy@lists.infradead.org
> Cc: linux-stm32@st-md-mailman.stormreply.com
> Cc: linux-usb@vger.kernel.org
> ---
> V2: - Fix up Sob/Cdb lines
> - Operate PHY as a syscon subnode
> V3: - Update copyright years
> - Register two sets of clock, one 480 MHz PLL and one CMN
> - Split PHY ops per PHY, since the PHY2 does not have set mode ops
> - Fix up Sob/Cdb lines further
> ---
> drivers/phy/st/Kconfig | 10 +
> drivers/phy/st/Makefile | 1 +
> drivers/phy/st/phy-stm32-usb2phy.c | 406 +++++++++++++++++++++++++++++
> 3 files changed, 417 insertions(+)
> create mode 100644 drivers/phy/st/phy-stm32-usb2phy.c
>
> diff --git a/drivers/phy/st/Kconfig b/drivers/phy/st/Kconfig
> index 49206185e5633..2835bb67bca9e 100644
> --- a/drivers/phy/st/Kconfig
> +++ b/drivers/phy/st/Kconfig
> @@ -58,3 +58,13 @@ config PHY_STM32_USBPHYC
> used by an HS USB Host controller, and the second one is shared
> between an HS USB OTG controller and an HS USB Host controller,
> selected by a USB switch.
> +
> +config PHY_STM32_USB2PHY
> + tristate "STMicroelectronics STM32MP25 USB2.0 PHY Controller driver"
> + depends on ARCH_STM32 || COMPILE_TEST
> + depends on COMMON_CLK
> + select GENERIC_PHY
> + help
> + Enable this to support the High-Speed USB 2.0 transceivers that are
> + part of the STMicroelectronics STM32MP25 SoCs. The PHY itself is a
> + Synopsys FEMTO-PHY.
> diff --git a/drivers/phy/st/Makefile b/drivers/phy/st/Makefile
> index cb80e954ea9f0..4945df5ed78a8 100644
> --- a/drivers/phy/st/Makefile
> +++ b/drivers/phy/st/Makefile
> @@ -5,3 +5,4 @@ obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
> obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o
> obj-$(CONFIG_PHY_STM32_COMBOPHY) += phy-stm32-combophy.o
> obj-$(CONFIG_PHY_STM32_USBPHYC) += phy-stm32-usbphyc.o
> +obj-$(CONFIG_PHY_STM32_USB2PHY) += phy-stm32-usb2phy.o
> diff --git a/drivers/phy/st/phy-stm32-usb2phy.c b/drivers/phy/st/phy-stm32-usb2phy.c
> new file mode 100644
> index 0000000000000..8c68b2d208d73
> --- /dev/null
> +++ b/drivers/phy/st/phy-stm32-usb2phy.c
> @@ -0,0 +1,406 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * STMicroelectronics STM32 USB2 PHY Controller driver
> + * Currently Only supported for STM32MP25
> + *
> + * Copyright (C) 2022-2026 STMicroelectronics
> + * Author(s): Pankaj Dev <pankaj.dev@st.com>.
> + */
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +#include <linux/usb/role.h>
> +#include <linux/mfd/syscon.h>
> +
> +#define SYSCFG_USB2PHY2CR_USB2PHY2CMN BIT(2)
> +#define SYSCFG_USB2PHY2CR_VBUSVALID BIT(4)
> +#define SYSCFG_USB2PHY2CR_VBUSVLDEXTSEL BIT(5)
> +#define SYSCFG_USB2PHY2CR_VBUSVLDEXT BIT(6)
> +
> +#define USBH_NUM_CLK 2
> +
> +struct stm32_usb2phy {
> + struct phy *phy;
> + struct regmap *regmap;
> + struct device *dev;
> + struct reset_control *rstc;
> + struct clk *phyref;
> + struct regulator *vdd33;
> + const struct stm32mp2_usb2phy_hw_data *hw_data;
> + atomic_t en_refcnt;
> + enum phy_mode mode;
> + u32 cr_offset;
> + bool is_init;
> + struct clk_hw clkpll_hw;
> + struct clk_hw clkcmn_hw;
> + /* Must be last */
> + struct clk_hw_onecell_data onecell;
> +};
> +
> +struct stm32mp2_usb2phy_hw_data {
> + u32 phyrefsel_mask;
> + const struct phy_ops *phy_ops;
> +};
> +
> +static int stm32_usb2phy_enable(struct stm32_usb2phy *phy_dev)
> +{
> + const struct stm32mp2_usb2phy_hw_data *phy_data = phy_dev->hw_data;
> + unsigned int refsel;
> + unsigned long rate;
> + int ret;
> +
> + /* Check if a phy is already init or clkpll in use */
> + if (atomic_inc_return(&phy_dev->en_refcnt) > 1)
> + return 0;
> +
> + rate = clk_get_rate(phy_dev->phyref);
> + if (rate == 19200000)
> + refsel = 0;
> + else if (rate == 20000000)
> + refsel = 1;
> + else if (rate == 24000000)
> + refsel = 2;
> + else
> + return -EINVAL;
> +
> + ret = regmap_update_bits(phy_dev->regmap,
> + phy_dev->cr_offset,
> + phy_data->phyrefsel_mask,
> + field_prep(phy_data->phyrefsel_mask, refsel));
> + if (ret)
> + return ret;
> +
> + ret = regulator_enable(phy_dev->vdd33);
> + if (ret)
> + return ret;
> +
> + ret = clk_prepare_enable(phy_dev->phyref);
> + if (ret)
> + goto error_regdis;
> +
> + ret = reset_control_deassert(phy_dev->rstc);
> + if (ret)
> + goto error_clkdis;
> +
> + return 0;
> +
> +error_clkdis:
> + clk_disable_unprepare(phy_dev->phyref);
> +error_regdis:
> + regulator_disable(phy_dev->vdd33);
> +
> + return ret;
> +}
> +
> +static int stm32_usb2phy_disable(struct stm32_usb2phy *phy_dev)
> +{
> + int ret;
> +
> + /* Check if a phy is still init or clkpll in use */
> + if (atomic_dec_return(&phy_dev->en_refcnt) > 0)
> + return 0;
> +
> + ret = reset_control_assert(phy_dev->rstc);
> + if (ret)
> + return ret;
> +
> + clk_disable_unprepare(phy_dev->phyref);
> +
> + return regulator_disable(phy_dev->vdd33);
> +}
> +
> +static int stm32_usb2phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
> +{
> + struct stm32_usb2phy *phy_dev = phy_get_drvdata(phy);
> + u32 mask = SYSCFG_USB2PHY2CR_USB2PHY2CMN |
> + SYSCFG_USB2PHY2CR_VBUSVALID |
> + SYSCFG_USB2PHY2CR_VBUSVLDEXT;
> + u32 val = 0;
> + int ret;
> +
> + if (mode == PHY_MODE_USB_HOST) {
> + if (submode != USB_ROLE_NONE)
> + val = SYSCFG_USB2PHY2CR_VBUSVALID;
> + } else if (mode == PHY_MODE_USB_DEVICE) {
> + val = SYSCFG_USB2PHY2CR_USB2PHY2CMN |
> + SYSCFG_USB2PHY2CR_VBUSVLDEXTSEL;
> + if (submode != USB_ROLE_NONE)
> + val |= SYSCFG_USB2PHY2CR_VBUSVLDEXT;
> + mask |= SYSCFG_USB2PHY2CR_VBUSVLDEXTSEL;
> + } else {
> + return -EINVAL;
> + }
> +
> + ret = regmap_update_bits(phy_dev->regmap, phy_dev->cr_offset, mask, val);
> + if (ret)
> + return ret;
> +
> + phy_dev->mode = mode;
> +
> + return 0;
> +}
> +
> +static int stm32_usb2phy1_init(struct phy *phy)
Hello Marek,
Could same init routine may be used for both PHYs ?
See below comment.
> +{
> + struct stm32_usb2phy *phy_dev = phy_get_drvdata(phy);
> + int ret;
> +
> + ret = stm32_usb2phy_enable(phy_dev);
> + if (ret)
> + return ret;
> +
> + phy_dev->is_init = true;
> +
> + return 0;
> +}
> +
> +static int stm32_usb2phy2_init(struct phy *phy)
> +{
> + struct stm32_usb2phy *phy_dev = phy_get_drvdata(phy);
> + int ret;
> +
> + ret = stm32_usb2phy_enable(phy_dev);
> + if (ret)
> + return ret;
> +
> + if (phy_dev->mode != PHY_MODE_INVALID) {
The only difference is here. On the PHY#1 the mode should never change
e.g. mode == PHY_MODE_INVALID. So same routine may be used for both PHYs ?
> + ret = stm32_usb2phy_set_mode(phy, phy_dev->mode, USB_ROLE_NONE);
> + if (ret) {
> + stm32_usb2phy_disable(phy_dev);
> + return ret;
> + }
> + }
> +
> + phy_dev->is_init = true;
> +
> + return 0;
> +}
> +
> +static int stm32_usb2phy_exit(struct phy *phy)
> +{
> + struct stm32_usb2phy *phy_dev = phy_get_drvdata(phy);
> + int ret;
> +
> + ret = stm32_usb2phy_disable(phy_dev);
> + if (ret)
> + return ret;
> +
> + phy_dev->is_init = false;
> +
> + return 0;
> +}
> +
> +static const struct phy_ops stm32_usb2phy1_data = {
> + .init = stm32_usb2phy1_init,
> + .exit = stm32_usb2phy_exit,
> + .owner = THIS_MODULE,
> +};
> +
> +static const struct phy_ops stm32_usb2phy2_data = {
> + .init = stm32_usb2phy2_init,
> + .exit = stm32_usb2phy_exit,
> + .set_mode = stm32_usb2phy_set_mode,
> + .owner = THIS_MODULE,
> +};
> +
> +static int stm32_usb2phy_clkpll_prepare(struct clk_hw *hw)
> +{
> + struct stm32_usb2phy *phy_dev = container_of(hw, struct stm32_usb2phy,
> + clkpll_hw);
> +
> + return stm32_usb2phy_enable(phy_dev);
> +}
> +
> +static void stm32_usb2phy_clkpll_unprepare(struct clk_hw *hw)
> +{
> + struct stm32_usb2phy *phy_dev = container_of(hw, struct stm32_usb2phy,
> + clkpll_hw);
> +
> + stm32_usb2phy_disable(phy_dev);
> +}
> +
> +static unsigned long stm32_usb2phy_clkpll_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + return 480000000;
> +}
> +
> +static const struct clk_ops stm32_usb2phy_clkpll_ops = {
> + .prepare = stm32_usb2phy_clkpll_prepare,
> + .unprepare = stm32_usb2phy_clkpll_unprepare,
> + .recalc_rate = stm32_usb2phy_clkpll_recalc_rate,
> +};
> +
> +static int stm32_usb2phy_clkcmn_prepare(struct clk_hw *hw)
> +{
> + struct stm32_usb2phy *phy_dev = container_of(hw, struct stm32_usb2phy,
> + clkcmn_hw);
> +
> + return regmap_clear_bits(phy_dev->regmap, phy_dev->cr_offset,
> + SYSCFG_USB2PHY2CR_USB2PHY2CMN);
> +}
> +
> +static void stm32_usb2phy_clkcmn_unprepare(struct clk_hw *hw)
> +{
> + struct stm32_usb2phy *phy_dev = container_of(hw, struct stm32_usb2phy,
> + clkcmn_hw);
> +
> + regmap_set_bits(phy_dev->regmap, phy_dev->cr_offset,
> + SYSCFG_USB2PHY2CR_USB2PHY2CMN);
> +}
> +
> +static const struct clk_ops stm32_usb2phy_clkcmn_ops = {
> + .prepare = stm32_usb2phy_clkcmn_prepare,
> + .unprepare = stm32_usb2phy_clkcmn_unprepare,
> +};
> +
> +static int stm32_usb2phy_probe(struct platform_device *pdev)
> +{
> + struct phy_provider *phy_provider;
> + struct device *dev = &pdev->dev;
> + struct stm32_usb2phy *phy_dev;
> + char *pllname, *cmnname;
> + const __be32 *offset;
> + struct phy *phy;
> + int ret;
> +
> + phy_dev = devm_kzalloc(dev, struct_size(phy_dev, onecell.hws, USBH_NUM_CLK), GFP_KERNEL);
> + if (!phy_dev)
> + return -ENOMEM;
> +
> + phy_dev->dev = dev;
> + dev_set_drvdata(dev, phy_dev);
> +
> + phy_dev->rstc = devm_reset_control_get(dev, NULL);
> + if (IS_ERR(phy_dev->rstc))
> + return dev_err_probe(dev, PTR_ERR(phy_dev->rstc), "Failed to get USB2PHY reset\n");
> +
> + phy_dev->phyref = devm_clk_get(dev, NULL);
> + if (IS_ERR(phy_dev->phyref))
> + return dev_err_probe(dev, PTR_ERR(phy_dev->phyref), "Failed to get phyref clk\n");
> +
> + phy_dev->vdd33 = devm_regulator_get_optional(dev, "vdd33");
> + if (IS_ERR(phy_dev->vdd33))
> + return dev_err_probe(dev, PTR_ERR(phy_dev->vdd33), "Failed to get vdd3v3 supply\n");
> +
> + phy_dev->regmap = syscon_node_to_regmap(dev->of_node->parent);
> + if (IS_ERR(phy_dev->regmap))
> + return dev_err_probe(dev, PTR_ERR(phy_dev->regmap), "Failed to get regmap\n");
> +
> + offset = of_get_address(dev->of_node, 0, NULL, NULL);
> + if (!offset)
> + return dev_err_probe(dev, -EINVAL, "Failed to get regmap offset\n");
> +
> + phy_dev->cr_offset = be32_to_cpu(*offset);
> +
> + phy_dev->hw_data = device_get_match_data(dev);
> +
> + phy = devm_phy_create(dev, NULL, phy_dev->hw_data->phy_ops);
> + if (IS_ERR(phy))
> + return dev_err_probe(dev, PTR_ERR(phy), "Failed to create PHY\n");
> +
> + phy_dev->phy = phy;
> + phy_set_drvdata(phy, phy_dev);
> +
> + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> + if (IS_ERR(phy_provider))
> + return PTR_ERR(phy_provider);
> +
> + pllname = devm_kasprintf(dev, GFP_KERNEL, "clk_%s_48m",
> + of_node_full_name(dev->of_node));
> + if (!pllname)
> + return -ENOMEM;
> +
> + cmnname = devm_kasprintf(dev, GFP_KERNEL, "clk_%s_cmn",
> + of_node_full_name(dev->of_node));
> + if (!cmnname)
> + return -ENOMEM;
> +
> + phy_dev->onecell.num = USBH_NUM_CLK;
> + phy_dev->onecell.hws[0] = &phy_dev->clkpll_hw;
> + phy_dev->onecell.hws[1] = &phy_dev->clkcmn_hw;
> +
> + phy_dev->clkpll_hw.init = CLK_HW_INIT_NO_PARENT(pllname, &stm32_usb2phy_clkpll_ops, 0);
> + ret = devm_clk_hw_register(phy_dev->dev, &phy_dev->clkpll_hw);
> + if (ret)
> + return dev_err_probe(phy_dev->dev, ret, "Failed to register PLL clock\n");
> +
> + phy_dev->clkcmn_hw.init = CLK_HW_INIT_HW(cmnname, &phy_dev->clkpll_hw,
> + &stm32_usb2phy_clkcmn_ops, 0);
> + ret = devm_clk_hw_register(phy_dev->dev, &phy_dev->clkcmn_hw);
> + if (ret)
> + return dev_err_probe(phy_dev->dev, ret, "Failed to register CMN clock\n");
> +
> + ret = devm_of_clk_add_hw_provider(phy_dev->dev, of_clk_hw_onecell_get, &phy_dev->onecell);
> + if (ret)
> + return dev_err_probe(phy_dev->dev, ret, "Failed to add clock provider\n");
> +
> + return 0;
> +}
> +
> +static int stm32_usb2phy_suspend(struct device *dev)
> +{
> + struct stm32_usb2phy *phy_dev = dev_get_drvdata(dev);
> +
> + if (phy_dev->is_init)
> + return stm32_usb2phy_disable(phy_dev);
> +
> + return 0;
> +}
> +
> +static int stm32_usb2phy_resume(struct device *dev)
> +{
> + struct stm32_usb2phy *phy_dev = dev_get_drvdata(dev);
> +
> + if (phy_dev->is_init)
> + return stm32_usb2phy_enable(phy_dev);
> +
> + return 0;
> +}
> +
> +/* STM32MP25xx USB 2.0 PHY attached to USB 2.0 Host controller */
> +static const struct stm32mp2_usb2phy_hw_data stm32mp25_usb2phy1_hwdata = {
> + .phyrefsel_mask = GENMASK(6, 4),
> + .phy_ops = &stm32_usb2phy1_data,
> +};
> +
> +/* STM32MP25xx USB 2.0 PHY attached to USB 2.0 part of DWC3 controller */
> +static const struct stm32mp2_usb2phy_hw_data stm32mp25_usb2phy2_hwdata = {
> + .phyrefsel_mask = GENMASK(14, 12),
> + .phy_ops = &stm32_usb2phy2_data,
> +};
> +
> +static const struct of_device_id stm32_usb2phy_of_match[] = {
> + { .compatible = "st,stm32mp25-usb2phy1", .data = &stm32mp25_usb2phy1_hwdata },
> + { .compatible = "st,stm32mp25-usb2phy2", .data = &stm32mp25_usb2phy2_hwdata },
> + { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, stm32_usb2phy_of_match);
> +
> +static DEFINE_SIMPLE_DEV_PM_OPS(stm32_usb2phy_pm_ops,
> + stm32_usb2phy_suspend, stm32_usb2phy_resume);
> +
> +static struct platform_driver stm32_usb2phy_driver = {
> + .probe = stm32_usb2phy_probe,
> + .driver = {
> + .name = "stm32-usb2phy",
> + .of_match_table = stm32_usb2phy_of_match,
> + .pm = pm_sleep_ptr(&stm32_usb2phy_pm_ops)
> + }
> +};
> +
> +module_platform_driver(stm32_usb2phy_driver);
> +
> +MODULE_AUTHOR("Pankaj Dev <pankaj.dev@st.com>");
> +MODULE_DESCRIPTION("STMicroelectronics Generic USB2PHY driver for stm32");
> +MODULE_LICENSE("GPL");
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v3 2/9] phy: stm32: Add support for ST STM32MP25 USB2-FEMTO PHY
2026-08-24 13:17 ` Fabrice Gasnier
@ 2026-08-24 14:53 ` Marek Vasut
0 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2026-08-24 14:53 UTC (permalink / raw)
To: Fabrice Gasnier, linux-usb
Cc: Pankaj Dev, Rahul Kumar, Christian Bruel, Alexandre Torgue,
Conor Dooley, Greg Kroah-Hartman, Krzysztof Kozlowski,
Maxime Coquelin, Neil Armstrong, Rob Herring, Rosen Penev,
Thinh Nguyen, Vinod Koul, devicetree, kernel, linux-arm-kernel,
linux-kernel, linux-phy, linux-stm32
On 8/24/26 3:17 PM, Fabrice Gasnier wrote:
[...]
Hello Fabrice,
>> +static int stm32_usb2phy1_init(struct phy *phy)
>
> Hello Marek,
>
> Could same init routine may be used for both PHYs ?
> See below comment.
>
>> +{
>> + struct stm32_usb2phy *phy_dev = phy_get_drvdata(phy);
>> + int ret;
>> +
>> + ret = stm32_usb2phy_enable(phy_dev);
>> + if (ret)
>> + return ret;
>> +
>> + phy_dev->is_init = true;
>> +
>> + return 0;
>> +}
>> +
>> +static int stm32_usb2phy2_init(struct phy *phy)
>> +{
>> + struct stm32_usb2phy *phy_dev = phy_get_drvdata(phy);
>> + int ret;
>> +
>> + ret = stm32_usb2phy_enable(phy_dev);
>> + if (ret)
>> + return ret;
>> +
>> + if (phy_dev->mode != PHY_MODE_INVALID) {
>
> The only difference is here. On the PHY#1 the mode should never change
> e.g. mode == PHY_MODE_INVALID. So same routine may be used for both PHYs ?
Since there are separate ops for each PHY, I opted for avoiding this
conditional on a PHY where the conditional makes no sense, hence the two
separate init functions.
>> + ret = stm32_usb2phy_set_mode(phy, phy_dev->mode, USB_ROLE_NONE);
>> + if (ret) {
>> + stm32_usb2phy_disable(phy_dev);
>> + return ret;
>> + }
>> + }
>> +
>> + phy_dev->is_init = true;
>> +
>> + return 0;
>> +}
[...]
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 3/9] dt-bindings: usb: generic-ehci: Document access-controllers property
2026-08-22 7:46 [PATCH v3 0/9] arm64: dts: phy: st: usb: Add STM32MP2 USB support Marek Vasut
2026-08-22 7:46 ` [PATCH v3 1/9] dt-bindings: phy: Document ST STM32MP25 USB2-FEMTO PHY Marek Vasut
2026-08-22 7:46 ` [PATCH v3 2/9] phy: stm32: Add support for " Marek Vasut
@ 2026-08-22 7:46 ` Marek Vasut
2026-08-22 7:46 ` [PATCH v3 4/9] dt-bindings: usb: generic-ohci: " Marek Vasut
` (5 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2026-08-22 7:46 UTC (permalink / raw)
To: linux-usb
Cc: fabrice.gasnier, Marek Vasut, Alexandre Torgue, Christian Bruel,
Conor Dooley, Greg Kroah-Hartman, Krzysztof Kozlowski,
Maxime Coquelin, Neil Armstrong, Pankaj Dev, Rahul Kumar,
Rob Herring, Rosen Penev, Thinh Nguyen, Vinod Koul, devicetree,
kernel, linux-arm-kernel, linux-kernel, linux-phy, linux-stm32
Document the access-controllers for EHCI USB controllers in case
access checks need to be performed to use them.
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Christian Bruel <christian.bruel@foss.st.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Pankaj Dev <pankaj.dev@st.com>
Cc: Rahul Kumar <rahul.kumar05@st.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Rosen Penev <rosenp@gmail.com>
Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: kernel@dh-electronics.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-usb@vger.kernel.org
---
V2: No change
V3: No change
---
Documentation/devicetree/bindings/usb/generic-ehci.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/usb/generic-ehci.yaml b/Documentation/devicetree/bindings/usb/generic-ehci.yaml
index ae9fb70d0212c..6bca56681cdfe 100644
--- a/Documentation/devicetree/bindings/usb/generic-ehci.yaml
+++ b/Documentation/devicetree/bindings/usb/generic-ehci.yaml
@@ -80,6 +80,9 @@ properties:
minItems: 1
maxItems: 2
+ access-controllers:
+ maxItems: 1
+
dma-coherent: true
interrupts:
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 4/9] dt-bindings: usb: generic-ohci: Document access-controllers property
2026-08-22 7:46 [PATCH v3 0/9] arm64: dts: phy: st: usb: Add STM32MP2 USB support Marek Vasut
` (2 preceding siblings ...)
2026-08-22 7:46 ` [PATCH v3 3/9] dt-bindings: usb: generic-ehci: Document access-controllers property Marek Vasut
@ 2026-08-22 7:46 ` Marek Vasut
2026-08-22 7:46 ` [PATCH v3 5/9] dt-bindings: usb: dwc3: Document ST STM32MP2 DWC3 xHCI USB controller Marek Vasut
` (4 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2026-08-22 7:46 UTC (permalink / raw)
To: linux-usb
Cc: fabrice.gasnier, Marek Vasut, Alexandre Torgue, Christian Bruel,
Conor Dooley, Greg Kroah-Hartman, Krzysztof Kozlowski,
Maxime Coquelin, Neil Armstrong, Pankaj Dev, Rahul Kumar,
Rob Herring, Rosen Penev, Thinh Nguyen, Vinod Koul, devicetree,
kernel, linux-arm-kernel, linux-kernel, linux-phy, linux-stm32
Document the access-controllers for OHCI USB controllers in case
access checks need to be performed to use them.
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Christian Bruel <christian.bruel@foss.st.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Pankaj Dev <pankaj.dev@st.com>
Cc: Rahul Kumar <rahul.kumar05@st.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Rosen Penev <rosenp@gmail.com>
Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: kernel@dh-electronics.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-usb@vger.kernel.org
---
V2: No change
V3: No change
---
Documentation/devicetree/bindings/usb/generic-ohci.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/usb/generic-ohci.yaml b/Documentation/devicetree/bindings/usb/generic-ohci.yaml
index 322808aaa2839..8e3522a3faa76 100644
--- a/Documentation/devicetree/bindings/usb/generic-ohci.yaml
+++ b/Documentation/devicetree/bindings/usb/generic-ohci.yaml
@@ -65,6 +65,9 @@ properties:
reg:
maxItems: 1
+ access-controllers:
+ maxItems: 1
+
dma-coherent: true
interrupts:
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 5/9] dt-bindings: usb: dwc3: Document ST STM32MP2 DWC3 xHCI USB controller
2026-08-22 7:46 [PATCH v3 0/9] arm64: dts: phy: st: usb: Add STM32MP2 USB support Marek Vasut
` (3 preceding siblings ...)
2026-08-22 7:46 ` [PATCH v3 4/9] dt-bindings: usb: generic-ohci: " Marek Vasut
@ 2026-08-22 7:46 ` Marek Vasut
2026-08-22 7:46 ` [PATCH v3 6/9] usb: dwc3: dwc3-generic-plat: Add ST STM32MP2 DWC3 xHCI USB controller glue Marek Vasut
` (3 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2026-08-22 7:46 UTC (permalink / raw)
To: linux-usb
Cc: fabrice.gasnier, Marek Vasut, Pankaj Dev, Clément Le Goffic,
Gatien Chevallier, Alexandre Torgue, Christian Bruel,
Conor Dooley, Greg Kroah-Hartman, Krzysztof Kozlowski,
Maxime Coquelin, Neil Armstrong, Rahul Kumar, Rob Herring,
Rosen Penev, Thinh Nguyen, Vinod Koul, devicetree, kernel,
linux-arm-kernel, linux-kernel, linux-phy, linux-stm32
The ST STM32MP2 SoC contains single instance of DWC3 USB controller with
glue logic wrapper around it controlled by syscon. Document the glue
logic and DWC3 controller.
Co-developed-by: Pankaj Dev <pankaj.dev@st.com>
Signed-off-by: Pankaj Dev <pankaj.dev@st.com>
Co-developed-by: Clément Le Goffic <clement.legoffic@foss.st.com>
Signed-off-by: Clément Le Goffic <clement.legoffic@foss.st.com>
Co-developed-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Christian Bruel <christian.bruel@foss.st.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Pankaj Dev <pankaj.dev@st.com>
Cc: Rahul Kumar <rahul.kumar05@st.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Rosen Penev <rosenp@gmail.com>
Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: kernel@dh-electronics.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-usb@vger.kernel.org
---
V2: Fix up Sob/Cdb lines
V3: - Document maximum-speed
- Switch resets to maxItems: 1
- Drop label from example
- Use generic over-current-active-low
- Use ref: snps,dwc3-common.yaml and drop generic dr_mode/maximum-speed/phys/phy-names
---
.../bindings/usb/st,stm32mp25-dwc3.yaml | 97 +++++++++++++++++++
1 file changed, 97 insertions(+)
create mode 100644 Documentation/devicetree/bindings/usb/st,stm32mp25-dwc3.yaml
diff --git a/Documentation/devicetree/bindings/usb/st,stm32mp25-dwc3.yaml b/Documentation/devicetree/bindings/usb/st,stm32mp25-dwc3.yaml
new file mode 100644
index 0000000000000..96bd557327252
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/st,stm32mp25-dwc3.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/st,stm32mp25-dwc3.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32 MPU DWC3 USB SoC controller
+
+description:
+ The STM32 MPU DWC3 USB SoC controller block supports both
+ Host(SS/HS/FS/LS) and Device(SS/HS/FS) mode operation
+
+maintainers:
+ - Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+ - Marek Vasut <marex@nabladev.com>
+
+allOf:
+ - $ref: snps,dwc3-common.yaml#
+
+properties:
+ compatible:
+ const: st,stm32mp25-dwc3
+
+ reg:
+ maxItems: 1
+
+ access-controllers:
+ maxItems: 1
+
+ clocks:
+ minItems: 3
+ maxItems: 3
+
+ clock-names:
+ items:
+ - const: ref
+ - const: bus_early
+ - const: suspend
+
+ interrupts:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+
+ over-current-active-low:
+ type: boolean
+ description: Over-Current signal polarity is active-low
+
+ st,syscfg:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ description: Phandle to system configuration controller.
+ items:
+ - items:
+ - description: phandle to syscfg
+ - description: USB3DR control offset within syscfg
+
+ st,enable-port-power-control:
+ type: boolean
+ description: Enable Host-Mode Port Power Control (bit-3 of capability param HCCPARAMS)
+
+ st,vbusen-active-low:
+ type: boolean
+ description: VBUS-ENABLE signal polarity is active-low
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - interrupts
+ - phys
+ - phy-names
+ - resets
+ - st,syscfg
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/st,stm32mp25-rcc.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/reset/st,stm32mp25-rcc.h>
+
+ usb@48300000 {
+ compatible = "st,stm32mp25-dwc3";
+ reg = <0x48300000 0x100000>;
+ clocks = <&rcc CK_KER_USB2PHY2>, <&rcc CK_BUS_USB3DR>, <&rcc CK_KER_USB2PHY2>;
+ clock-names = "ref", "bus_early", "suspend";
+ interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy>, <&usb3_phy>;
+ phy-names = "usb2-phy", "usb3-phy";
+ resets = <&rcc USB3DR_R>;
+ over-current-active-low;
+ st,syscfg = <&syscfg 0x4800>;
+ st,vbusen-active-low;
+ };
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 6/9] usb: dwc3: dwc3-generic-plat: Add ST STM32MP2 DWC3 xHCI USB controller glue
2026-08-22 7:46 [PATCH v3 0/9] arm64: dts: phy: st: usb: Add STM32MP2 USB support Marek Vasut
` (4 preceding siblings ...)
2026-08-22 7:46 ` [PATCH v3 5/9] dt-bindings: usb: dwc3: Document ST STM32MP2 DWC3 xHCI USB controller Marek Vasut
@ 2026-08-22 7:46 ` Marek Vasut
2026-08-22 7:56 ` sashiko-bot
2026-08-22 7:46 ` [PATCH v3 7/9] dt-bindings: arm: stm32: Switch st,stm32mp23/25-syscfg into simple-mfd Marek Vasut
` (2 subsequent siblings)
8 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2026-08-22 7:46 UTC (permalink / raw)
To: linux-usb
Cc: fabrice.gasnier, Marek Vasut, Alexandre Torgue, Christian Bruel,
Conor Dooley, Greg Kroah-Hartman, Krzysztof Kozlowski,
Maxime Coquelin, Neil Armstrong, Pankaj Dev, Rahul Kumar,
Rob Herring, Rosen Penev, Thinh Nguyen, Vinod Koul, devicetree,
kernel, linux-arm-kernel, linux-kernel, linux-phy, linux-stm32
The ST STM32MP2 SoC contains one instance of DWC3 USB controller with
glue logic wrapper around it controlled by syscon. Extend the generic
DWC3 platform driver with ST STM32MP2 glue logic specifics.
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Christian Bruel <christian.bruel@foss.st.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Pankaj Dev <pankaj.dev@st.com>
Cc: Rahul Kumar <rahul.kumar05@st.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Rosen Penev <rosenp@gmail.com>
Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: kernel@dh-electronics.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-usb@vger.kernel.org
---
V2: No change
V3: - Use generic over-current-active-low
---
drivers/usb/dwc3/dwc3-generic-plat.c | 44 ++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/drivers/usb/dwc3/dwc3-generic-plat.c b/drivers/usb/dwc3/dwc3-generic-plat.c
index ca69ac0eb07ce..f670576511b59 100644
--- a/drivers/usb/dwc3/dwc3-generic-plat.c
+++ b/drivers/usb/dwc3/dwc3-generic-plat.c
@@ -22,6 +22,12 @@
#define EIC7700_HSP_AXI_LP_XM_CSYSREQ BIT(0)
#define EIC7700_HSP_AXI_LP_XS_CSYSREQ BIT(16)
+#define STM32MP2_USB3DRCR_HOST_PORT_POWER_CONTROL_PRESENT BIT(0)
+#define STM32MP2_USB3DRCR_OVRCUR_POLARITY BIT(1)
+#define STM32MP2_USB3DRCR_VBUSEN_POLARITY BIT(2)
+#define STM32MP2_USB3DRCR_USB2ONLYH BIT(3)
+#define STM32MP2_USB3DRCR_USB2ONLYD BIT(4)
+
struct dwc3_generic {
struct device *dev;
struct dwc3 dwc;
@@ -85,6 +91,38 @@ static int dwc3_spacemit_k1_init(struct dwc3_generic *dwc3g)
return 0;
}
+static int dwc3_stm32mp25_init(struct dwc3_generic *dwc3g)
+{
+ struct device *dev = dwc3g->dev;
+ bool ovrcur_polarity_low = device_property_read_bool(dev, "over-current-active-low");
+ bool prt_pwr_ctrl = device_property_read_bool(dev, "st,enable-port-power-control");
+ bool usb2only_conf = device_property_match_string(dev, "phy-names", "usb3-phy") < 0;
+ bool vbusen_polarity_low = device_property_read_bool(dev, "st,vbusen-active-low");
+ struct regmap *regmap;
+ u32 drcr;
+
+ regmap = syscon_regmap_lookup_by_phandle_args(dev->of_node, "st,syscfg", 1, &drcr);
+ if (IS_ERR(regmap))
+ return dev_err_probe(dev, PTR_ERR(regmap), "No st,syscfg phandle specified\n");
+
+ return regmap_update_bits(regmap, drcr,
+ STM32MP2_USB3DRCR_HOST_PORT_POWER_CONTROL_PRESENT |
+ STM32MP2_USB3DRCR_OVRCUR_POLARITY |
+ STM32MP2_USB3DRCR_VBUSEN_POLARITY |
+ STM32MP2_USB3DRCR_USB2ONLYD |
+ STM32MP2_USB3DRCR_USB2ONLYH,
+ FIELD_PREP(STM32MP2_USB3DRCR_HOST_PORT_POWER_CONTROL_PRESENT,
+ prt_pwr_ctrl) |
+ FIELD_PREP(STM32MP2_USB3DRCR_OVRCUR_POLARITY,
+ ovrcur_polarity_low) |
+ FIELD_PREP(STM32MP2_USB3DRCR_VBUSEN_POLARITY,
+ vbusen_polarity_low) |
+ FIELD_PREP(STM32MP2_USB3DRCR_USB2ONLYD,
+ !!usb2only_conf) |
+ FIELD_PREP(STM32MP2_USB3DRCR_USB2ONLYH,
+ !!usb2only_conf));
+}
+
static int dwc3_generic_probe(struct platform_device *pdev)
{
const struct dwc3_generic_config *plat_config;
@@ -231,12 +269,18 @@ static const struct dwc3_generic_config eic7700_dwc3 = {
.properties = DWC3_DEFAULT_PROPERTIES,
};
+static const struct dwc3_generic_config stm32mp25_dwc3 = {
+ .init = dwc3_stm32mp25_init,
+ .properties = DWC3_DEFAULT_PROPERTIES,
+};
+
static const struct of_device_id dwc3_generic_of_match[] = {
{ .compatible = "spacemit,k1-dwc3", &spacemit_k1_dwc3},
{ .compatible = "spacemit,k3-dwc3", },
{ .compatible = "fsl,ls1028a-dwc3", &fsl_ls1028_dwc3},
{ .compatible = "eswin,eic7700-dwc3", &eic7700_dwc3},
{ .compatible = "starfive,jhb100-dwc3", },
+ { .compatible = "st,stm32mp25-dwc3", &stm32mp25_dwc3 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dwc3_generic_of_match);
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v3 6/9] usb: dwc3: dwc3-generic-plat: Add ST STM32MP2 DWC3 xHCI USB controller glue
2026-08-22 7:46 ` [PATCH v3 6/9] usb: dwc3: dwc3-generic-plat: Add ST STM32MP2 DWC3 xHCI USB controller glue Marek Vasut
@ 2026-08-22 7:56 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-08-22 7:56 UTC (permalink / raw)
To: Marek Vasut
Cc: vkoul, neil.armstrong, linux-phy, conor+dt, devicetree, robh,
olteanv
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The file uses the FIELD_PREP macro without including its required header <linux/bitfield.h>.
--
--- Patch [6]: [PATCH v3 6/9] usb: dwc3: dwc3-generic-plat: Add ST STM32MP2 DWC3 xHCI USB controller glue ---
commit 144f9fcc747a522925bb8e40158fa496caf2673c
Author: Marek Vasut <marex@nabladev.com>
usb: dwc3: dwc3-generic-plat: Add ST STM32MP2 DWC3 xHCI USB controller glue
This commit extends the generic DWC3 platform driver by adding glue logic
support for the ST STM32MP2 SoC. It configures controller settings using
syscon via device tree properties.
> diff --git a/drivers/usb/dwc3/dwc3-generic-plat.c b/drivers/usb/dwc3/dwc3-generic-plat.c
> index ca69ac0eb07ce..f670576511b59 100644
> --- a/drivers/usb/dwc3/dwc3-generic-plat.c
> +++ b/drivers/usb/dwc3/dwc3-generic-plat.c
[ ... ]
> @@ -85,6 +91,38 @@ static int dwc3_spacemit_k1_init(struct dwc3_generic *dwc3g)
[ ... ]
> +static int dwc3_stm32mp25_init(struct dwc3_generic *dwc3g)
> +{
[ ... ]
> + return regmap_update_bits(regmap, drcr,
> + STM32MP2_USB3DRCR_HOST_PORT_POWER_CONTROL_PRESENT |
> + STM32MP2_USB3DRCR_OVRCUR_POLARITY |
> + STM32MP2_USB3DRCR_VBUSEN_POLARITY |
> + STM32MP2_USB3DRCR_USB2ONLYD |
> + STM32MP2_USB3DRCR_USB2ONLYH,
> + FIELD_PREP(STM32MP2_USB3DRCR_HOST_PORT_POWER_CONTROL_PRESENT,
> + prt_pwr_ctrl) |
[Severity: Low]
This isn't a bug, but FIELD_PREP is used here without explicitly including
linux/bitfield.h. Could this cause build failures on architectures or
configurations where this header is not implicitly pulled in by other
includes?
> + FIELD_PREP(STM32MP2_USB3DRCR_OVRCUR_POLARITY,
> + ovrcur_polarity_low) |
> + FIELD_PREP(STM32MP2_USB3DRCR_VBUSEN_POLARITY,
> + vbusen_polarity_low) |
> + FIELD_PREP(STM32MP2_USB3DRCR_USB2ONLYD,
> + !!usb2only_conf) |
> + FIELD_PREP(STM32MP2_USB3DRCR_USB2ONLYH,
> + !!usb2only_conf));
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260822074816.548662-1-marex@nabladev.com?part=6
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 7/9] dt-bindings: arm: stm32: Switch st,stm32mp23/25-syscfg into simple-mfd
2026-08-22 7:46 [PATCH v3 0/9] arm64: dts: phy: st: usb: Add STM32MP2 USB support Marek Vasut
` (5 preceding siblings ...)
2026-08-22 7:46 ` [PATCH v3 6/9] usb: dwc3: dwc3-generic-plat: Add ST STM32MP2 DWC3 xHCI USB controller glue Marek Vasut
@ 2026-08-22 7:46 ` Marek Vasut
2026-08-22 8:01 ` sashiko-bot
2026-08-22 7:46 ` [PATCH v3 8/9] arm64: dts: st: Add USB nodes on stm32mp231 Marek Vasut
2026-08-22 7:46 ` [PATCH v3 9/9] arm64: dts: st: Add USB nodes on stm32mp251 Marek Vasut
8 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2026-08-22 7:46 UTC (permalink / raw)
To: linux-usb
Cc: fabrice.gasnier, Marek Vasut, Alexandre Torgue, Christian Bruel,
Conor Dooley, Greg Kroah-Hartman, Krzysztof Kozlowski,
Maxime Coquelin, Neil Armstrong, Pankaj Dev, Rahul Kumar,
Rob Herring, Rosen Penev, Thinh Nguyen, Vinod Koul, devicetree,
kernel, linux-arm-kernel, linux-kernel, linux-phy, linux-stm32
The st,stm32mp23-syscfg and st,stm32mp25-syscfg can have subnodes, which
represent the USB 2.0 FEMTO-PHY. Turn the syscfg into "simple-mfd" so the
PHYs would get populated by the OS.
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Christian Bruel <christian.bruel@foss.st.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Pankaj Dev <pankaj.dev@st.com>
Cc: Rahul Kumar <rahul.kumar05@st.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Rosen Penev <rosenp@gmail.com>
Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: kernel@dh-electronics.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-usb@vger.kernel.org
---
V2: New patch
V3: Fix the bindings
---
.../bindings/arm/stm32/st,stm32-syscon.yaml | 24 +++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml b/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
index 95d2319afe235..4db4198c5dd7a 100644
--- a/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
+++ b/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
@@ -22,11 +22,12 @@ properties:
- st,stm32mp151-pwr-mcu
- st,stm32mp157-syscfg
- st,stm32mp21-syscfg
- - st,stm32mp23-syscfg
- - st,stm32mp25-syscfg
- const: syscon
- items:
- - const: st,stm32-tamp
+ - enum:
+ - st,stm32-tamp
+ - st,stm32mp23-syscfg
+ - st,stm32mp25-syscfg
- const: syscon
- const: simple-mfd
@@ -39,6 +40,17 @@ properties:
"#clock-cells":
const: 0
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 1
+
+patternProperties:
+ "^phy@[0-9a-f]+$":
+ type: object
+ $ref: /schemas/phy/st,stm32-usb2phy.yaml
+
required:
- compatible
- reg
@@ -57,10 +69,14 @@ allOf:
- if:
properties:
compatible:
- const: st,stm32mp25-syscfg
+ enum:
+ - st,stm32mp23-syscfg
+ - st,stm32mp25-syscfg
then:
required:
- "#clock-cells"
+ - "#address-cells"
+ - "#size-cells"
additionalProperties: false
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v3 7/9] dt-bindings: arm: stm32: Switch st,stm32mp23/25-syscfg into simple-mfd
2026-08-22 7:46 ` [PATCH v3 7/9] dt-bindings: arm: stm32: Switch st,stm32mp23/25-syscfg into simple-mfd Marek Vasut
@ 2026-08-22 8:01 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-08-22 8:01 UTC (permalink / raw)
To: Marek Vasut
Cc: devicetree, linux-phy, vkoul, neil.armstrong, robh, olteanv,
conor+dt
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Critical] Strictly enforcing `simple-mfd` in the compatible array breaks backward compatibility with existing device trees.
- [High] The `en_refcnt` atomic reference counter is leaked on error paths in `stm32_usb2phy_enable()`, permanently breaking the PHY.
- [Medium] The `allOf:if` condition for `st,stm32mp23/25-syscfg` uses `enum` directly on the `compatible` property array, bypassing the validation block.
- [Low] The `patternProperties` regex in the syscon parent binding rejects the `usb-phy@` node name recommended by the child PHY binding.
--
--- Patch [7]: [PATCH v3 7/9] dt-bindings: arm: stm32: Switch st,stm32mp23/25-syscfg into simple-mfd ---
commit 4dd8eb77acf0eb2b46ea02d08826b4d490de3fb4
Author: Marek Vasut <marex@nabladev.com>
dt-bindings: arm: stm32: Switch st,stm32mp23/25-syscfg into simple-mfd
This commit updates the STM32 syscon binding to convert the
st,stm32mp23-syscfg and st,stm32mp25-syscfg compatibles into "simple-mfd".
This allows the OS to automatically populate the subnodes for the USB 2.0
FEMTO-PHY.
> diff --git a/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml b/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
> index 95d2319afe235..4db4198c5dd7a 100644
> --- a/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
> +++ b/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
> @@ -22,11 +22,12 @@ properties:
> - st,stm32mp151-pwr-mcu
> - st,stm32mp157-syscfg
> - st,stm32mp21-syscfg
> - - st,stm32mp23-syscfg
> - - st,stm32mp25-syscfg
> - const: syscon
> - items:
> - - const: st,stm32-tamp
> + - enum:
> + - st,stm32-tamp
> + - st,stm32mp23-syscfg
> + - st,stm32mp25-syscfg
> + - const: syscon
> + - const: simple-mfd
[Severity: Critical]
Does enforcing simple-mfd in this array break backward compatibility?
Older device trees define these syscfg nodes using only st,stm32mp25-syscfg
and syscon. Moving them into a strict 3-item list requiring simple-mfd
causes validation to fail for existing DTBs.
> @@ -39,6 +40,17 @@ properties:
> "#clock-cells":
> const: 0
>
> + "#address-cells":
> + const: 1
> +
> + "#size-cells":
> + const: 1
> +
> +patternProperties:
> + "^phy@[0-9a-f]+$":
> + type: object
> + $ref: /schemas/phy/st,stm32-usb2phy.yaml
[Severity: Low]
Will this regex reject the node names recommended by the child PHY binding?
The child binding example uses usb-phy@2400:
usb-phy@2400 {
compatible = "st,stm32mp25-usb2phy1";
which fails the stricter ^phy@[0-9a-f]+$ pattern defined here.
[ ... ]
> @@ -57,10 +69,14 @@ allOf:
> - if:
> properties:
> compatible:
> - const: st,stm32mp25-syscfg
> + enum:
> + - st,stm32mp23-syscfg
> + - st,stm32mp25-syscfg
[Severity: Medium]
Does this conditional block bypass schema validation?
Applying enum directly to an array property checks if the array strictly
equals the scalar string, which always evaluates to false. Should this use
contains: enum: instead?
> then:
> required:
> - "#clock-cells"
> + - "#address-cells"
> + - "#size-cells"
[Severity: High]
Is there a reference counter leak in stm32_usb2phy_enable() introduced
earlier in this series?
If an unsupported clock rate is detected, the function returns without
decrementing en_refcnt:
drivers/phy/st/phy-stm32-usb2phy.c:stm32_usb2phy_enable() {
...
if (...)
...
else
return -EINVAL;
}
Additionally, the common error paths do not decrement en_refcnt after it
was incremented:
drivers/phy/st/phy-stm32-usb2phy.c:stm32_usb2phy_enable() {
...
error_regdis:
regulator_disable(phy_dev->vdd33);
return ret;
}
Future calls will see en_refcnt > 1 and return success immediately, leaving
the PHY disabled.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260822074816.548662-1-marex@nabladev.com?part=7
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 8/9] arm64: dts: st: Add USB nodes on stm32mp231
2026-08-22 7:46 [PATCH v3 0/9] arm64: dts: phy: st: usb: Add STM32MP2 USB support Marek Vasut
` (6 preceding siblings ...)
2026-08-22 7:46 ` [PATCH v3 7/9] dt-bindings: arm: stm32: Switch st,stm32mp23/25-syscfg into simple-mfd Marek Vasut
@ 2026-08-22 7:46 ` Marek Vasut
2026-08-22 8:07 ` sashiko-bot
2026-08-24 13:18 ` Fabrice Gasnier
2026-08-22 7:46 ` [PATCH v3 9/9] arm64: dts: st: Add USB nodes on stm32mp251 Marek Vasut
8 siblings, 2 replies; 21+ messages in thread
From: Marek Vasut @ 2026-08-22 7:46 UTC (permalink / raw)
To: linux-usb
Cc: fabrice.gasnier, Marek Vasut, Alexandre Torgue, Francois Choleau,
Christian Bruel, Conor Dooley, Greg Kroah-Hartman,
Krzysztof Kozlowski, Maxime Coquelin, Neil Armstrong, Pankaj Dev,
Rahul Kumar, Rob Herring, Rosen Penev, Thinh Nguyen, Vinod Koul,
devicetree, kernel, linux-arm-kernel, linux-kernel, linux-phy,
linux-stm32
Add USB controller and PHY nodes to stm32mp231 DT.
This includes two USB 2.0 FEMTO PHYs, USB 2.0 host
controller and DWC3 DRD controller nodes.
Co-developed-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
Co-developed-by: Francois Choleau <francois.choleau@st.com>
Signed-off-by: Francois Choleau <francois.choleau@st.com>
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Christian Bruel <christian.bruel@foss.st.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Pankaj Dev <pankaj.dev@st.com>
Cc: Rahul Kumar <rahul.kumar05@st.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Rosen Penev <rosenp@gmail.com>
Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: kernel@dh-electronics.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-usb@vger.kernel.org
---
V2: - Fix up Sob/Cdb lines
- Move PHY into syscfg subnode
- Turn st,stm32mp23-syscfg into simple-mfd
- Use clock-cells = <1> to discern OSC and future PLL clock from the PHY
V3: - Drop combophy which is not present on MP23
- Describe OHCI clock as the CMN clock
---
arch/arm64/boot/dts/st/stm32mp231.dtsi | 67 +++++++++++++++++++++++++-
1 file changed, 66 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/st/stm32mp231.dtsi b/arch/arm64/boot/dts/st/stm32mp231.dtsi
index 4505fc0e3b537..314a514f31024 100644
--- a/arch/arm64/boot/dts/st/stm32mp231.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp231.dtsi
@@ -7,6 +7,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/regulator/st,stm32mp25-regulator.h>
#include <dt-bindings/reset/st,stm32mp25-rcc.h>
+#include <dt-bindings/phy/phy.h>
/ {
#address-cells = <2>;
@@ -862,6 +863,48 @@ stmmac_axi_config_1: stmmac-axi-config {
snps,wr_osr_lmt = <0x7>;
};
};
+
+ usbh_ohci: usb@482e0000 {
+ compatible = "generic-ohci";
+ reg = <0x482e0000 0x1000>;
+ access-controllers = <&rifsc 63>;
+ clocks = <&usb2_phy1 1>, <&rcc CK_BUS_USB2OHCI>;
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy1>;
+ phy-names = "usb";
+ resets = <&rcc USBH_R>;
+ status = "disabled";
+ };
+
+ usbh_ehci: usb@482f0000 {
+ compatible = "generic-ehci";
+ reg = <0x482f0000 0x1000>;
+ access-controllers = <&rifsc 63>;
+ clocks = <&usb2_phy1 0>, <&rcc CK_BUS_USB2EHCI>;
+ companion = <&usbh_ohci>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy1>;
+ phy-names = "usb";
+ resets = <&rcc USBH_R>;
+ status = "disabled";
+ };
+
+ usb3dr: usb@48300000 {
+ compatible = "st,stm32mp25-dwc3";
+ reg = <0x48300000 0x100000>;
+ access-controllers = <&rifsc 66>;
+ clocks = <&rcc CK_KER_USB2PHY2>,
+ <&rcc CK_BUS_USB3DR>,
+ <&rcc CK_KER_USB2PHY2>;
+ clock-names = "ref", "bus_early", "suspend";
+ interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
+ maximum-speed = "high-speed";
+ phys = <&usb2_phy2>;
+ phy-names = "usb2-phy";
+ resets = <&rcc USB3DR_R>;
+ st,syscfg = <&syscfg 0x4800>;
+ status = "disabled";
+ };
};
bsec: efuse@44000000 {
@@ -1062,9 +1105,31 @@ exti1: interrupt-controller@44220000 {
};
syscfg: syscon@44230000 {
- compatible = "st,stm32mp23-syscfg", "syscon";
+ compatible = "st,stm32mp23-syscfg", "syscon", "simple-mfd";
reg = <0x44230000 0x10000>;
#clock-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ usb2_phy1: phy@2400 {
+ compatible = "st,stm32mp25-usb2phy1";
+ reg = <0x2400 0x24>;
+ #phy-cells = <0>;
+ #clock-cells = <1>;
+ clocks = <&rcc CK_KER_USB2PHY1>;
+ resets = <&rcc USB2PHY1_R>;
+ status = "disabled";
+ };
+
+ usb2_phy2: phy@2800 {
+ compatible = "st,stm32mp25-usb2phy2";
+ reg = <0x2800 0xc>;
+ #phy-cells = <0>;
+ #clock-cells = <1>;
+ clocks = <&rcc CK_KER_USB2PHY2EN>;
+ resets = <&rcc USB2PHY2_R>;
+ status = "disabled";
+ };
};
pinctrl: pinctrl@44240000 {
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v3 8/9] arm64: dts: st: Add USB nodes on stm32mp231
2026-08-22 7:46 ` [PATCH v3 8/9] arm64: dts: st: Add USB nodes on stm32mp231 Marek Vasut
@ 2026-08-22 8:07 ` sashiko-bot
2026-08-24 13:18 ` Fabrice Gasnier
1 sibling, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-08-22 8:07 UTC (permalink / raw)
To: Marek Vasut
Cc: neil.armstrong, robh, olteanv, devicetree, conor+dt, vkoul,
linux-phy
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Missing `ranges` property in the `simple-mfd` `syscfg` node causes a kernel WARN_ON during boot.
--
--- Patch [8]: [PATCH v3 8/9] arm64: dts: st: Add USB nodes on stm32mp231 ---
commit b21748ed09e5c154d11bfc7972df50b9735bfab9
Author: Marek Vasut <marex@nabladev.com>
arm64: dts: st: Add USB nodes on stm32mp231
This commit adds USB controller and PHY nodes to the stm32mp231 device tree.
It also converts the syscfg node into a simple-mfd to contain the new PHY
subnodes.
> diff --git a/arch/arm64/boot/dts/st/stm32mp231.dtsi b/arch/arm64/boot/dts/st/stm32mp231.dtsi
> index 9e1d240888ff2..db66777a8c9a0 100644
> --- a/arch/arm64/boot/dts/st/stm32mp231.dtsi
> +++ b/arch/arm64/boot/dts/st/stm32mp231.dtsi
[ ... ]
> syscfg: syscon@44230000 {
> - compatible = "st,stm32mp23-syscfg", "syscon";
> + compatible = "st,stm32mp23-syscfg", "syscon", "simple-mfd";
> reg = <0x44230000 0x10000>;
> #clock-cells = <0>;
> + #address-cells = <1>;
> + #size-cells = <1>;
[Severity: Medium]
Is there a missing ranges property here?
Since the syscfg node is now a simple-mfd bus with children that have reg
properties (usb2_phy1 and usb2_phy2), omitting the ranges property causes
address translation to fail.
During boot, when of_platform_populate() tries to instantiate the children,
of_address_to_resource() will fail to translate the child addresses. This
triggers a WARN_ON() in drivers/of/platform.c:of_device_alloc() for each
child device, which pollutes the boot log and could cause boot failures if
panic_on_warn is enabled.
> +
> + usb2_phy1: phy@2400 {
> + compatible = "st,stm32mp25-usb2phy1";
> + reg = <0x2400 0x24>;
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260822074816.548662-1-marex@nabladev.com?part=8
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v3 8/9] arm64: dts: st: Add USB nodes on stm32mp231
2026-08-22 7:46 ` [PATCH v3 8/9] arm64: dts: st: Add USB nodes on stm32mp231 Marek Vasut
2026-08-22 8:07 ` sashiko-bot
@ 2026-08-24 13:18 ` Fabrice Gasnier
2026-08-24 14:39 ` Marek Vasut
1 sibling, 1 reply; 21+ messages in thread
From: Fabrice Gasnier @ 2026-08-24 13:18 UTC (permalink / raw)
To: Marek Vasut, linux-usb
Cc: Alexandre Torgue, Francois Choleau, Christian Bruel, Conor Dooley,
Greg Kroah-Hartman, Krzysztof Kozlowski, Maxime Coquelin,
Neil Armstrong, Pankaj Dev, Rahul Kumar, Rob Herring, Rosen Penev,
Thinh Nguyen, Vinod Koul, devicetree, kernel, linux-arm-kernel,
linux-kernel, linux-phy, linux-stm32
On 8/22/26 09:46, Marek Vasut wrote:
> Add USB controller and PHY nodes to stm32mp231 DT.
> This includes two USB 2.0 FEMTO PHYs, USB 2.0 host
> controller and DWC3 DRD controller nodes.
>
> Co-developed-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
> Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
> Co-developed-by: Francois Choleau <francois.choleau@st.com>
> Signed-off-by: Francois Choleau <francois.choleau@st.com>
> Signed-off-by: Marek Vasut <marex@nabladev.com>
> ---
> Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
> Cc: Christian Bruel <christian.bruel@foss.st.com>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> Cc: Neil Armstrong <neil.armstrong@linaro.org>
> Cc: Pankaj Dev <pankaj.dev@st.com>
> Cc: Rahul Kumar <rahul.kumar05@st.com>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Rosen Penev <rosenp@gmail.com>
> Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
> Cc: Vinod Koul <vkoul@kernel.org>
> Cc: devicetree@vger.kernel.org
> Cc: kernel@dh-electronics.com
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-phy@lists.infradead.org
> Cc: linux-stm32@st-md-mailman.stormreply.com
> Cc: linux-usb@vger.kernel.org
> ---
> V2: - Fix up Sob/Cdb lines
> - Move PHY into syscfg subnode
> - Turn st,stm32mp23-syscfg into simple-mfd
> - Use clock-cells = <1> to discern OSC and future PLL clock from the PHY
> V3: - Drop combophy which is not present on MP23
> - Describe OHCI clock as the CMN clock
> ---
> arch/arm64/boot/dts/st/stm32mp231.dtsi | 67 +++++++++++++++++++++++++-
> 1 file changed, 66 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/st/stm32mp231.dtsi b/arch/arm64/boot/dts/st/stm32mp231.dtsi
> index 4505fc0e3b537..314a514f31024 100644
> --- a/arch/arm64/boot/dts/st/stm32mp231.dtsi
> +++ b/arch/arm64/boot/dts/st/stm32mp231.dtsi
> @@ -7,6 +7,7 @@
> #include <dt-bindings/interrupt-controller/arm-gic.h>
> #include <dt-bindings/regulator/st,stm32mp25-regulator.h>
> #include <dt-bindings/reset/st,stm32mp25-rcc.h>
> +#include <dt-bindings/phy/phy.h>
>
> / {
> #address-cells = <2>;
> @@ -862,6 +863,48 @@ stmmac_axi_config_1: stmmac-axi-config {
> snps,wr_osr_lmt = <0x7>;
> };
> };
> +
> + usbh_ohci: usb@482e0000 {
> + compatible = "generic-ohci";
> + reg = <0x482e0000 0x1000>;
> + access-controllers = <&rifsc 63>;
> + clocks = <&usb2_phy1 1>, <&rcc CK_BUS_USB2OHCI>;
> + interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
> + phys = <&usb2_phy1>;
> + phy-names = "usb";
> + resets = <&rcc USBH_R>;
> + status = "disabled";
> + };
> +
> + usbh_ehci: usb@482f0000 {
> + compatible = "generic-ehci";
> + reg = <0x482f0000 0x1000>;
> + access-controllers = <&rifsc 63>;
> + clocks = <&usb2_phy1 0>, <&rcc CK_BUS_USB2EHCI>;
> + companion = <&usbh_ohci>;
> + interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
> + phys = <&usb2_phy1>;
> + phy-names = "usb";
> + resets = <&rcc USBH_R>;
> + status = "disabled";
> + };
> +
> + usb3dr: usb@48300000 {
> + compatible = "st,stm32mp25-dwc3";
> + reg = <0x48300000 0x100000>;
> + access-controllers = <&rifsc 66>;
> + clocks = <&rcc CK_KER_USB2PHY2>,
> + <&rcc CK_BUS_USB3DR>,
> + <&rcc CK_KER_USB2PHY2>;
> + clock-names = "ref", "bus_early", "suspend";
> + interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
> + maximum-speed = "high-speed";
> + phys = <&usb2_phy2>;
> + phy-names = "usb2-phy";
> + resets = <&rcc USB3DR_R>;
> + st,syscfg = <&syscfg 0x4800>;
> + status = "disabled";
> + };
> };
>
> bsec: efuse@44000000 {
> @@ -1062,9 +1105,31 @@ exti1: interrupt-controller@44220000 {
> };
>
> syscfg: syscon@44230000 {
> - compatible = "st,stm32mp23-syscfg", "syscon";
> + compatible = "st,stm32mp23-syscfg", "syscon", "simple-mfd";
> reg = <0x44230000 0x10000>;
> #clock-cells = <0>;
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + usb2_phy1: phy@2400 {
> + compatible = "st,stm32mp25-usb2phy1";
> + reg = <0x2400 0x24>;
Hello Marek,
The size 0x24, covers the PHY control, trimming and vbus control logic
for PHY1 (USBH). So this allows to later extend the driver for that, right ?
> + #phy-cells = <0>;
> + #clock-cells = <1>;
> + clocks = <&rcc CK_KER_USB2PHY1>;
> + resets = <&rcc USB2PHY1_R>;
> + status = "disabled";
> + };
> +
> + usb2_phy2: phy@2800 {
> + compatible = "st,stm32mp25-usb2phy2";
> + reg = <0x2800 0xc>;
Then here, I guess the size should cover also trimming regs ? e.g. 0x10 ?
reg = <0x2800 0x10>;
Thanks & BR,
Fabrice
> + #phy-cells = <0>;
> + #clock-cells = <1>;
> + clocks = <&rcc CK_KER_USB2PHY2EN>;
> + resets = <&rcc USB2PHY2_R>;
> + status = "disabled";
> + };
> };
>
> pinctrl: pinctrl@44240000 {
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v3 8/9] arm64: dts: st: Add USB nodes on stm32mp231
2026-08-24 13:18 ` Fabrice Gasnier
@ 2026-08-24 14:39 ` Marek Vasut
0 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2026-08-24 14:39 UTC (permalink / raw)
To: Fabrice Gasnier, linux-usb
Cc: Alexandre Torgue, Francois Choleau, Christian Bruel, Conor Dooley,
Greg Kroah-Hartman, Krzysztof Kozlowski, Maxime Coquelin,
Neil Armstrong, Pankaj Dev, Rahul Kumar, Rob Herring, Rosen Penev,
Thinh Nguyen, Vinod Koul, devicetree, kernel, linux-arm-kernel,
linux-kernel, linux-phy, linux-stm32
On 8/24/26 3:18 PM, Fabrice Gasnier wrote:
[...]
>> syscfg: syscon@44230000 {
>> - compatible = "st,stm32mp23-syscfg", "syscon";
>> + compatible = "st,stm32mp23-syscfg", "syscon", "simple-mfd";
>> reg = <0x44230000 0x10000>;
>> #clock-cells = <0>;
>> + #address-cells = <1>;
>> + #size-cells = <1>;
>> +
>> + usb2_phy1: phy@2400 {
>> + compatible = "st,stm32mp25-usb2phy1";
>> + reg = <0x2400 0x24>;
>
> Hello Marek,
Hello Fabrice,
> The size 0x24, covers the PHY control, trimming and vbus control logic
> for PHY1 (USBH). So this allows to later extend the driver for that, right ?
Correct.
>> + #phy-cells = <0>;
>> + #clock-cells = <1>;
>> + clocks = <&rcc CK_KER_USB2PHY1>;
>> + resets = <&rcc USB2PHY1_R>;
>> + status = "disabled";
>> + };
>> +
>> + usb2_phy2: phy@2800 {
>> + compatible = "st,stm32mp25-usb2phy2";
>> + reg = <0x2800 0xc>;
>
> Then here, I guess the size should cover also trimming regs ? e.g. 0x10 ?
> reg = <0x2800 0x10>;
Uh, yes, fixed in V4, thanks !
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 9/9] arm64: dts: st: Add USB nodes on stm32mp251
2026-08-22 7:46 [PATCH v3 0/9] arm64: dts: phy: st: usb: Add STM32MP2 USB support Marek Vasut
` (7 preceding siblings ...)
2026-08-22 7:46 ` [PATCH v3 8/9] arm64: dts: st: Add USB nodes on stm32mp231 Marek Vasut
@ 2026-08-22 7:46 ` Marek Vasut
2026-08-24 13:19 ` Fabrice Gasnier
8 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2026-08-22 7:46 UTC (permalink / raw)
To: linux-usb
Cc: fabrice.gasnier, Pankaj Dev, Marek Vasut, Alexandre Torgue,
Christian Bruel, Conor Dooley, Greg Kroah-Hartman,
Krzysztof Kozlowski, Maxime Coquelin, Neil Armstrong, Rahul Kumar,
Rob Herring, Rosen Penev, Thinh Nguyen, Vinod Koul, devicetree,
kernel, linux-arm-kernel, linux-kernel, linux-phy, linux-stm32
From: Pankaj Dev <pankaj.dev@st.com>
Add USB controller and PHY nodes to stm32mp251 DT.
This includes two USB 2.0 FEMTO PHYs, USB 2.0 host
controller and DWC3 DRD controller nodes.
Signed-off-by: Pankaj Dev <pankaj.dev@st.com>
Co-developed-by: Marek Vasut <marex@nabladev.com>
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Christian Bruel <christian.bruel@foss.st.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Pankaj Dev <pankaj.dev@st.com>
Cc: Rahul Kumar <rahul.kumar05@st.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Rosen Penev <rosenp@gmail.com>
Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: kernel@dh-electronics.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-usb@vger.kernel.org
---
V2: - Fix up Sob/Cdb lines
- Move PHY into syscfg subnode
- Turn st,stm32mp25-syscfg into simple-mfd
- Use clock-cells = <1> to discern OSC and future PLL clock from the PHY
V3: - Describe OHCI clock as the CMN clock
- Fix up Sob/Cdb lines further
---
arch/arm64/boot/dts/st/stm32mp251.dtsi | 65 +++++++++++++++++++++++++-
1 file changed, 64 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 6e985f115b195..dd2f7ddd9b634 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -1746,6 +1746,47 @@ stmmac_axi_config_1: stmmac-axi-config {
};
};
+ usbh_ohci: usb@482e0000 {
+ compatible = "generic-ohci";
+ reg = <0x482e0000 0x1000>;
+ access-controllers = <&rifsc 63>;
+ clocks = <&usb2_phy1 1>, <&rcc CK_BUS_USB2OHCI>;
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy1>;
+ phy-names = "usb";
+ resets = <&rcc USBH_R>;
+ status = "disabled";
+ };
+
+ usbh_ehci: usb@482f0000 {
+ compatible = "generic-ehci";
+ reg = <0x482f0000 0x1000>;
+ access-controllers = <&rifsc 63>;
+ clocks = <&usb2_phy1 0>, <&rcc CK_BUS_USB2EHCI>;
+ companion = <&usbh_ohci>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy1>;
+ phy-names = "usb";
+ resets = <&rcc USBH_R>;
+ status = "disabled";
+ };
+
+ usb3dr: usb@48300000 {
+ compatible = "st,stm32mp25-dwc3";
+ reg = <0x48300000 0x100000>;
+ access-controllers = <&rifsc 66>;
+ clocks = <&rcc CK_KER_USB2PHY2>,
+ <&rcc CK_BUS_USB3DR>,
+ <&rcc CK_KER_USB2PHY2>;
+ clock-names = "ref", "bus_early", "suspend";
+ interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy2>, <&combophy PHY_TYPE_USB3>;
+ phy-names = "usb2-phy", "usb3-phy";
+ resets = <&rcc USB3DR_R>;
+ st,syscfg = <&syscfg 0x4800>;
+ status = "disabled";
+ };
+
pcie_ep: pcie-ep@48400000 {
compatible = "st,stm32mp25-pcie-ep";
reg = <0x48400000 0x100000>,
@@ -2002,9 +2043,31 @@ exti1: interrupt-controller@44220000 {
};
syscfg: syscon@44230000 {
- compatible = "st,stm32mp25-syscfg", "syscon";
+ compatible = "st,stm32mp25-syscfg", "syscon", "simple-mfd";
reg = <0x44230000 0x10000>;
#clock-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ usb2_phy1: phy@2400 {
+ compatible = "st,stm32mp25-usb2phy1";
+ reg = <0x2400 0x24>;
+ #phy-cells = <0>;
+ #clock-cells = <1>;
+ clocks = <&rcc CK_KER_USB2PHY1>;
+ resets = <&rcc USB2PHY1_R>;
+ status = "disabled";
+ };
+
+ usb2_phy2: phy@2800 {
+ compatible = "st,stm32mp25-usb2phy2";
+ reg = <0x2800 0xc>;
+ #phy-cells = <0>;
+ #clock-cells = <1>;
+ clocks = <&rcc CK_KER_USB2PHY2EN>;
+ resets = <&rcc USB2PHY2_R>;
+ status = "disabled";
+ };
};
pinctrl: pinctrl@44240000 {
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v3 9/9] arm64: dts: st: Add USB nodes on stm32mp251
2026-08-22 7:46 ` [PATCH v3 9/9] arm64: dts: st: Add USB nodes on stm32mp251 Marek Vasut
@ 2026-08-24 13:19 ` Fabrice Gasnier
2026-08-24 14:39 ` Marek Vasut
0 siblings, 1 reply; 21+ messages in thread
From: Fabrice Gasnier @ 2026-08-24 13:19 UTC (permalink / raw)
To: Marek Vasut, linux-usb
Cc: Pankaj Dev, Alexandre Torgue, Christian Bruel, Conor Dooley,
Greg Kroah-Hartman, Krzysztof Kozlowski, Maxime Coquelin,
Neil Armstrong, Rahul Kumar, Rob Herring, Rosen Penev,
Thinh Nguyen, Vinod Koul, devicetree, kernel, linux-arm-kernel,
linux-kernel, linux-phy, linux-stm32
On 8/22/26 09:46, Marek Vasut wrote:
> From: Pankaj Dev <pankaj.dev@st.com>
>
> Add USB controller and PHY nodes to stm32mp251 DT.
> This includes two USB 2.0 FEMTO PHYs, USB 2.0 host
> controller and DWC3 DRD controller nodes.
>
> Signed-off-by: Pankaj Dev <pankaj.dev@st.com>
> Co-developed-by: Marek Vasut <marex@nabladev.com>
> Signed-off-by: Marek Vasut <marex@nabladev.com>
> ---
> Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
> Cc: Christian Bruel <christian.bruel@foss.st.com>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> Cc: Neil Armstrong <neil.armstrong@linaro.org>
> Cc: Pankaj Dev <pankaj.dev@st.com>
> Cc: Rahul Kumar <rahul.kumar05@st.com>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Rosen Penev <rosenp@gmail.com>
> Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
> Cc: Vinod Koul <vkoul@kernel.org>
> Cc: devicetree@vger.kernel.org
> Cc: kernel@dh-electronics.com
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-phy@lists.infradead.org
> Cc: linux-stm32@st-md-mailman.stormreply.com
> Cc: linux-usb@vger.kernel.org
> ---
> V2: - Fix up Sob/Cdb lines
> - Move PHY into syscfg subnode
> - Turn st,stm32mp25-syscfg into simple-mfd
> - Use clock-cells = <1> to discern OSC and future PLL clock from the PHY
> V3: - Describe OHCI clock as the CMN clock
> - Fix up Sob/Cdb lines further
> ---
> arch/arm64/boot/dts/st/stm32mp251.dtsi | 65 +++++++++++++++++++++++++-
> 1 file changed, 64 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
> index 6e985f115b195..dd2f7ddd9b634 100644
> --- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
> +++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
> @@ -1746,6 +1746,47 @@ stmmac_axi_config_1: stmmac-axi-config {
> };
> };
>
> + usbh_ohci: usb@482e0000 {
> + compatible = "generic-ohci";
> + reg = <0x482e0000 0x1000>;
> + access-controllers = <&rifsc 63>;
> + clocks = <&usb2_phy1 1>, <&rcc CK_BUS_USB2OHCI>;
> + interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
> + phys = <&usb2_phy1>;
> + phy-names = "usb";
> + resets = <&rcc USBH_R>;
> + status = "disabled";
> + };
> +
> + usbh_ehci: usb@482f0000 {
> + compatible = "generic-ehci";
> + reg = <0x482f0000 0x1000>;
> + access-controllers = <&rifsc 63>;
> + clocks = <&usb2_phy1 0>, <&rcc CK_BUS_USB2EHCI>;
> + companion = <&usbh_ohci>;
> + interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
> + phys = <&usb2_phy1>;
> + phy-names = "usb";
> + resets = <&rcc USBH_R>;
> + status = "disabled";
> + };
> +
> + usb3dr: usb@48300000 {
> + compatible = "st,stm32mp25-dwc3";
> + reg = <0x48300000 0x100000>;
> + access-controllers = <&rifsc 66>;
> + clocks = <&rcc CK_KER_USB2PHY2>,
> + <&rcc CK_BUS_USB3DR>,
> + <&rcc CK_KER_USB2PHY2>;
> + clock-names = "ref", "bus_early", "suspend";
> + interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
> + phys = <&usb2_phy2>, <&combophy PHY_TYPE_USB3>;
> + phy-names = "usb2-phy", "usb3-phy";
> + resets = <&rcc USB3DR_R>;
> + st,syscfg = <&syscfg 0x4800>;
> + status = "disabled";
> + };
> +
> pcie_ep: pcie-ep@48400000 {
> compatible = "st,stm32mp25-pcie-ep";
> reg = <0x48400000 0x100000>,
> @@ -2002,9 +2043,31 @@ exti1: interrupt-controller@44220000 {
> };
>
> syscfg: syscon@44230000 {
> - compatible = "st,stm32mp25-syscfg", "syscon";
> + compatible = "st,stm32mp25-syscfg", "syscon", "simple-mfd";
> reg = <0x44230000 0x10000>;
> #clock-cells = <0>;
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + usb2_phy1: phy@2400 {
> + compatible = "st,stm32mp25-usb2phy1";
> + reg = <0x2400 0x24>;
> + #phy-cells = <0>;
> + #clock-cells = <1>;
> + clocks = <&rcc CK_KER_USB2PHY1>;
> + resets = <&rcc USB2PHY1_R>;
> + status = "disabled";
> + };
> +
> + usb2_phy2: phy@2800 {
> + compatible = "st,stm32mp25-usb2phy2";
> + reg = <0x2800 0xc>;
Hello Marek,
Similar to stm32mp231: should update size ?
reg = <0x2800 0x10>;
Thanks & BR,
Fabrice
> + #phy-cells = <0>;
> + #clock-cells = <1>;
> + clocks = <&rcc CK_KER_USB2PHY2EN>;
> + resets = <&rcc USB2PHY2_R>;
> + status = "disabled";
> + };
> };
>
> pinctrl: pinctrl@44240000 {
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v3 9/9] arm64: dts: st: Add USB nodes on stm32mp251
2026-08-24 13:19 ` Fabrice Gasnier
@ 2026-08-24 14:39 ` Marek Vasut
0 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2026-08-24 14:39 UTC (permalink / raw)
To: Fabrice Gasnier, linux-usb
Cc: Pankaj Dev, Alexandre Torgue, Christian Bruel, Conor Dooley,
Greg Kroah-Hartman, Krzysztof Kozlowski, Maxime Coquelin,
Neil Armstrong, Rahul Kumar, Rob Herring, Rosen Penev,
Thinh Nguyen, Vinod Koul, devicetree, kernel, linux-arm-kernel,
linux-kernel, linux-phy, linux-stm32
On 8/24/26 3:19 PM, Fabrice Gasnier wrote:
Hello Fabrice,
>> + usb2_phy2: phy@2800 {
>> + compatible = "st,stm32mp25-usb2phy2";
>> + reg = <0x2800 0xc>;
>
> Hello Marek,
>
> Similar to stm32mp231: should update size ?
>
> reg = <0x2800 0x10>;
Fixed in V4, thanks !
^ permalink raw reply [flat|nested] 21+ messages in thread