* [PATCH v8 0/5] Modify interrupt handling for eUSB2 Phy targets
@ 2026-09-13 14:40 ` Krishna Kurapati
0 siblings, 0 replies; 14+ messages in thread
From: Krishna Kurapati @ 2026-09-13 14:40 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thinh Nguyen,
Greg Kroah-Hartman
Cc: linux-phy, devicetree, linux-kernel, linux-arm-msm, linux-usb,
Krishna Kurapati, Krzysztof Kozlowski, Manivannan Sadhasivam,
Konrad Dybcio
eUSB2 targets handle wakeup interrupts differently depending on device
speed when operating in host mode.
According to the eUSB2 specification, remote wakeup signaling in host
mode is detected via different data-line assertions based on the
connected device speed.
When a low-speed device is connected, the host repeater drives eD+ to
logic '1' upon detecting a K-state on the USB lines during remote wakeup
(eUSB2 specification, Section 5.5.14).
When a full-speed or high-speed device is connected, the host repeater
drives eD- to logic '1' upon detecting a K-state on the USB line during
remote wakeup (eUSB2 specification, Sections 5.5.15 and 5.5.18).
Since the eUSB2 PHY's "DP" and "DM" interrupt lines monitor the eD+ and
eD- line states, configure the wakeup interrupts accordingly
Add support for a new phy "type" attribute to be set by eusb2 phy drivers
and be read by consumers (in this case usb controller) and act accordingly
Changes pushed on top of usb-next branch. And v8 is only compile tested.
Changes in v8:
Rebase on top of latest usb-next
Link to v7:
https://lore.kernel.org/all/20260905-eusb2-interrupt-v7-v7-0-820cf5377a70@oss.qualcomm.com/
Changes in v7:
- Removed NULL check for phy pointer.
Link to v6:
https://lore.kernel.org/all/20260826-eusb2-interrupt-v6-v6-0-ae2601cfa80c@oss.qualcomm.com/
Changes in v6:
- Update commit messages to reflect why new EUSB2 phy type is added
- Update phy reading via index rather than by name
- Remove redundant header files in phy driver changes
Link to v5:
https://lore.kernel.org/all/20260723-eusb2-int-handling-v5-v5-0-f32ea6c1a318@oss.qualcomm.com/
Changes in v5:
- Add support for phy "type" attribute and set it from m31 and snps eusb2
phy probes.
- Removed adding a new binding property
Link to v4:
https://lore.kernel.org/all/20260709-eusb2-interrupt-handling-v5-v4-0-d4f993925608@oss.qualcomm.com/
Changes in v4:
- Moved to using binding approach as suggested by Thinh
Link to v3:
https://lore.kernel.org/all/20260511094422.3561509-1-krishna.kurapati@oss.qualcomm.com/
Changes in v3:
- Removed multiple glymur-dwc3-mp pdata entries
- Replaced use of ternary operators with if-else
Link to v2:
https://lore.kernel.org/all/20260505194242.1947891-1-krishna.kurapati@oss.qualcomm.com/
Changes in v2:
- Updated commit message
- added supported eUSB2 targets
Link to v1:
https://lore.kernel.org/all/20260502095616.666938-1-krishna.kurapati@oss.qualcomm.com/
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
---
Krishna Kurapati (5):
dt-bindings: phy: Add PHY_TYPE_EUSB2 definition
include: linux: phy: Add phy attribute "type" and associated helpers
phy: snps-eusb2: Set phy type to EUSB2
phy: qcom: m31-eusb2: Set phy type to EUSB2
usb: dwc3: qcom: Modify interrupt handling for eUSB2 Phy targets
drivers/phy/phy-snps-eusb2.c | 2 +
drivers/phy/qualcomm/phy-qcom-m31-eusb2.c | 2 +
drivers/usb/dwc3/dwc3-qcom.c | 63 +++++++++++++++++++++++--------
include/dt-bindings/phy/phy.h | 1 +
include/linux/phy/phy.h | 27 +++++++++++++
5 files changed, 80 insertions(+), 15 deletions(-)
---
base-commit: ed2050bc671b44b2c948dbd4347cc534d44ccc9f
change-id: 20260913-eusb2-interrupt-v8-ec30991dba4e
Best regards,
--
Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v8 1/5] dt-bindings: phy: Add PHY_TYPE_EUSB2 definition
2026-09-13 14:40 ` Krishna Kurapati
@ 2026-09-13 14:40 ` Krishna Kurapati
-1 siblings, 0 replies; 14+ messages in thread
From: Krishna Kurapati @ 2026-09-13 14:40 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thinh Nguyen,
Greg Kroah-Hartman
Cc: linux-phy, devicetree, linux-kernel, linux-arm-msm, linux-usb,
Krishna Kurapati, Krzysztof Kozlowski, Manivannan Sadhasivam
eUSB2 (Embedded USB2) is a MIPI Alliance standard for chip-to-chip USB2
signaling. Unlike standard USB2, which uses 3.3V signaling, eUSB2 uses
low-voltage differential signaling (~0.4V) and requires a repeater to
interface with external USB2 ports. Because of these differences, eUSB2
PHY initialization sequences, voltage tuning, and register configuration
are distinct from USB2.
Additionally, eUSB2 targets handle wakeup interrupts differently
depending on device speed when operating in host mode. According to the
eUSB2 specification, remote wakeup signaling in host mode is detected
via different data-line assertions based on the connected device speed:
- Low-speed devices: the host repeater drives eD+ to logic '1' upon
detecting a K-state on the USB lines during remote wakeup (eUSB2
spec, Section 5.5.14).
- Full-speed/high-speed devices: the host repeater drives eD- to
logic '1' upon detecting a K-state during remote wakeup (eUSB2 spec,
Sections 5.5.15 and 5.5.18).
Since the eUSB2 PHY's DP and DM lines need to be configured differently
from USB2 PHYs, controllers should be able to query the PHY type and
configure wakeup interrupts accordingly.
Add PHY_TYPE_EUSB2 to distinguish eUSB2 PHYs from standard USB2 PHYs.
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
---
include/dt-bindings/phy/phy.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h
index 979b5dfd8353..555a022c8c0b 100644
--- a/include/dt-bindings/phy/phy.h
+++ b/include/dt-bindings/phy/phy.h
@@ -24,6 +24,7 @@
#define PHY_TYPE_CPHY 11
#define PHY_TYPE_USXGMII 12
#define PHY_TYPE_XAUI 13
+#define PHY_TYPE_EUSB2 14
#define PHY_POL_NORMAL 0
#define PHY_POL_INVERT 1
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 1/5] dt-bindings: phy: Add PHY_TYPE_EUSB2 definition
@ 2026-09-13 14:40 ` Krishna Kurapati
0 siblings, 0 replies; 14+ messages in thread
From: Krishna Kurapati @ 2026-09-13 14:40 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thinh Nguyen,
Greg Kroah-Hartman
Cc: linux-phy, devicetree, linux-kernel, linux-arm-msm, linux-usb,
Krishna Kurapati, Krzysztof Kozlowski, Manivannan Sadhasivam
eUSB2 (Embedded USB2) is a MIPI Alliance standard for chip-to-chip USB2
signaling. Unlike standard USB2, which uses 3.3V signaling, eUSB2 uses
low-voltage differential signaling (~0.4V) and requires a repeater to
interface with external USB2 ports. Because of these differences, eUSB2
PHY initialization sequences, voltage tuning, and register configuration
are distinct from USB2.
Additionally, eUSB2 targets handle wakeup interrupts differently
depending on device speed when operating in host mode. According to the
eUSB2 specification, remote wakeup signaling in host mode is detected
via different data-line assertions based on the connected device speed:
- Low-speed devices: the host repeater drives eD+ to logic '1' upon
detecting a K-state on the USB lines during remote wakeup (eUSB2
spec, Section 5.5.14).
- Full-speed/high-speed devices: the host repeater drives eD- to
logic '1' upon detecting a K-state during remote wakeup (eUSB2 spec,
Sections 5.5.15 and 5.5.18).
Since the eUSB2 PHY's DP and DM lines need to be configured differently
from USB2 PHYs, controllers should be able to query the PHY type and
configure wakeup interrupts accordingly.
Add PHY_TYPE_EUSB2 to distinguish eUSB2 PHYs from standard USB2 PHYs.
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
---
include/dt-bindings/phy/phy.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h
index 979b5dfd8353..555a022c8c0b 100644
--- a/include/dt-bindings/phy/phy.h
+++ b/include/dt-bindings/phy/phy.h
@@ -24,6 +24,7 @@
#define PHY_TYPE_CPHY 11
#define PHY_TYPE_USXGMII 12
#define PHY_TYPE_XAUI 13
+#define PHY_TYPE_EUSB2 14
#define PHY_POL_NORMAL 0
#define PHY_POL_INVERT 1
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 2/5] include: linux: phy: Add phy attribute "type" and associated helpers
2026-09-13 14:40 ` Krishna Kurapati
@ 2026-09-13 14:40 ` Krishna Kurapati
-1 siblings, 0 replies; 14+ messages in thread
From: Krishna Kurapati @ 2026-09-13 14:40 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thinh Nguyen,
Greg Kroah-Hartman
Cc: linux-phy, devicetree, linux-kernel, linux-arm-msm, linux-usb,
Krishna Kurapati, Manivannan Sadhasivam
In cases like USB High-speed phys which can be either USB2 or EUSB2, it is
required to know the type of phy (rather than the operating mode) because
DP and DM interrupt lines need to be configured differently for each of
them.
Add support to cache the PHY_TYPE and add the following helpers:
- phy_set_type() for the phy drivers (like m31_eusb2 or snps-eusb2) to
declare what type of PHY they are (in this case PHY_TYPE_EUSB2).
- phy_get_type() for the consumers (like USB controllers) to query the
type of phy connected to them.
Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
---
include/linux/phy/phy.h | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index ea47975e288a..038c2b58bbe1 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -21,6 +21,8 @@
#include <linux/phy/phy-lvds.h>
#include <linux/phy/phy-mipi-dphy.h>
+#include <dt-bindings/phy/phy.h>
+
struct phy;
enum phy_mode {
@@ -152,11 +154,13 @@ struct phy_ops {
* @bus_width: Data path width implemented by PHY
* @max_link_rate: Maximum link rate supported by PHY (units to be decided by producer and consumer)
* @mode: PHY mode
+ * @type: PHY type
*/
struct phy_attrs {
u32 bus_width;
u32 max_link_rate;
enum phy_mode mode;
+ int type;
};
/**
@@ -262,6 +266,20 @@ static inline enum phy_mode phy_get_mode(struct phy *phy)
{
return phy->attrs.mode;
}
+
+static inline int phy_get_type(struct phy *phy)
+{
+ if (phy)
+ return phy->attrs.type;
+
+ return PHY_NONE;
+}
+
+static inline void phy_set_type(struct phy *phy, int type)
+{
+ phy->attrs.type = type;
+}
+
int phy_reset(struct phy *phy);
int phy_calibrate(struct phy *phy);
int phy_notify_connect(struct phy *phy, int port);
@@ -393,6 +411,15 @@ static inline enum phy_mode phy_get_mode(struct phy *phy)
return PHY_MODE_INVALID;
}
+static inline int phy_get_type(struct phy *phy)
+{
+ return PHY_NONE;
+}
+
+static inline void phy_set_type(struct phy *phy, int type)
+{
+}
+
static inline int phy_reset(struct phy *phy)
{
if (!phy)
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v8 2/5] include: linux: phy: Add phy attribute "type" and associated helpers
@ 2026-09-13 14:40 ` Krishna Kurapati
0 siblings, 0 replies; 14+ messages in thread
From: Krishna Kurapati @ 2026-09-13 14:40 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thinh Nguyen,
Greg Kroah-Hartman
Cc: linux-phy, devicetree, linux-kernel, linux-arm-msm, linux-usb,
Krishna Kurapati, Manivannan Sadhasivam
In cases like USB High-speed phys which can be either USB2 or EUSB2, it is
required to know the type of phy (rather than the operating mode) because
DP and DM interrupt lines need to be configured differently for each of
them.
Add support to cache the PHY_TYPE and add the following helpers:
- phy_set_type() for the phy drivers (like m31_eusb2 or snps-eusb2) to
declare what type of PHY they are (in this case PHY_TYPE_EUSB2).
- phy_get_type() for the consumers (like USB controllers) to query the
type of phy connected to them.
Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
---
include/linux/phy/phy.h | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index ea47975e288a..038c2b58bbe1 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -21,6 +21,8 @@
#include <linux/phy/phy-lvds.h>
#include <linux/phy/phy-mipi-dphy.h>
+#include <dt-bindings/phy/phy.h>
+
struct phy;
enum phy_mode {
@@ -152,11 +154,13 @@ struct phy_ops {
* @bus_width: Data path width implemented by PHY
* @max_link_rate: Maximum link rate supported by PHY (units to be decided by producer and consumer)
* @mode: PHY mode
+ * @type: PHY type
*/
struct phy_attrs {
u32 bus_width;
u32 max_link_rate;
enum phy_mode mode;
+ int type;
};
/**
@@ -262,6 +266,20 @@ static inline enum phy_mode phy_get_mode(struct phy *phy)
{
return phy->attrs.mode;
}
+
+static inline int phy_get_type(struct phy *phy)
+{
+ if (phy)
+ return phy->attrs.type;
+
+ return PHY_NONE;
+}
+
+static inline void phy_set_type(struct phy *phy, int type)
+{
+ phy->attrs.type = type;
+}
+
int phy_reset(struct phy *phy);
int phy_calibrate(struct phy *phy);
int phy_notify_connect(struct phy *phy, int port);
@@ -393,6 +411,15 @@ static inline enum phy_mode phy_get_mode(struct phy *phy)
return PHY_MODE_INVALID;
}
+static inline int phy_get_type(struct phy *phy)
+{
+ return PHY_NONE;
+}
+
+static inline void phy_set_type(struct phy *phy, int type)
+{
+}
+
static inline int phy_reset(struct phy *phy)
{
if (!phy)
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 3/5] phy: snps-eusb2: Set phy type to EUSB2
2026-09-13 14:40 ` Krishna Kurapati
@ 2026-09-13 14:40 ` Krishna Kurapati
-1 siblings, 0 replies; 14+ messages in thread
From: Krishna Kurapati @ 2026-09-13 14:40 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thinh Nguyen,
Greg Kroah-Hartman
Cc: linux-phy, devicetree, linux-kernel, linux-arm-msm, linux-usb,
Krishna Kurapati, Manivannan Sadhasivam
USB controllers like DWC3 are agnostic of the kind of phy (USB2/eUSB2)
connected to it. Set the phy type to EUSB2 to let the controller know
the phy type when queried during its probe.
Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
---
drivers/phy/phy-snps-eusb2.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/phy/phy-snps-eusb2.c b/drivers/phy/phy-snps-eusb2.c
index af4fa17ac6cb..ab405108c727 100644
--- a/drivers/phy/phy-snps-eusb2.c
+++ b/drivers/phy/phy-snps-eusb2.c
@@ -596,6 +596,8 @@ static int snps_eusb2_hsphy_probe(struct platform_device *pdev)
return PTR_ERR(generic_phy);
}
+ phy_set_type(generic_phy, PHY_TYPE_EUSB2);
+
dev_set_drvdata(dev, phy);
phy_set_drvdata(generic_phy, phy);
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 3/5] phy: snps-eusb2: Set phy type to EUSB2
@ 2026-09-13 14:40 ` Krishna Kurapati
0 siblings, 0 replies; 14+ messages in thread
From: Krishna Kurapati @ 2026-09-13 14:40 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thinh Nguyen,
Greg Kroah-Hartman
Cc: linux-phy, devicetree, linux-kernel, linux-arm-msm, linux-usb,
Krishna Kurapati, Manivannan Sadhasivam
USB controllers like DWC3 are agnostic of the kind of phy (USB2/eUSB2)
connected to it. Set the phy type to EUSB2 to let the controller know
the phy type when queried during its probe.
Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
---
drivers/phy/phy-snps-eusb2.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/phy/phy-snps-eusb2.c b/drivers/phy/phy-snps-eusb2.c
index af4fa17ac6cb..ab405108c727 100644
--- a/drivers/phy/phy-snps-eusb2.c
+++ b/drivers/phy/phy-snps-eusb2.c
@@ -596,6 +596,8 @@ static int snps_eusb2_hsphy_probe(struct platform_device *pdev)
return PTR_ERR(generic_phy);
}
+ phy_set_type(generic_phy, PHY_TYPE_EUSB2);
+
dev_set_drvdata(dev, phy);
phy_set_drvdata(generic_phy, phy);
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 4/5] phy: qcom: m31-eusb2: Set phy type to EUSB2
2026-09-13 14:40 ` Krishna Kurapati
@ 2026-09-13 14:40 ` Krishna Kurapati
-1 siblings, 0 replies; 14+ messages in thread
From: Krishna Kurapati @ 2026-09-13 14:40 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thinh Nguyen,
Greg Kroah-Hartman
Cc: linux-phy, devicetree, linux-kernel, linux-arm-msm, linux-usb,
Krishna Kurapati, Manivannan Sadhasivam
USB controllers like DWC3 are agnostic of the kind of phy (USB2/eUSB2)
connected to it. Set the phy type to EUSB2 to let the controller know
the phy type when queried during its probe.
Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-m31-eusb2.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c b/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
index 275df38256de..72fa71003fd9 100644
--- a/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
@@ -277,6 +277,8 @@ static int m31eusb2_phy_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(phy->phy),
"failed to create phy\n");
+ phy_set_type(phy->phy, PHY_TYPE_EUSB2);
+
ret = devm_regulator_bulk_get_const(dev, M31_EUSB_NUM_VREGS,
m31_eusb_phy_vregs, &phy->vregs);
if (ret)
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 4/5] phy: qcom: m31-eusb2: Set phy type to EUSB2
@ 2026-09-13 14:40 ` Krishna Kurapati
0 siblings, 0 replies; 14+ messages in thread
From: Krishna Kurapati @ 2026-09-13 14:40 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thinh Nguyen,
Greg Kroah-Hartman
Cc: linux-phy, devicetree, linux-kernel, linux-arm-msm, linux-usb,
Krishna Kurapati, Manivannan Sadhasivam
USB controllers like DWC3 are agnostic of the kind of phy (USB2/eUSB2)
connected to it. Set the phy type to EUSB2 to let the controller know
the phy type when queried during its probe.
Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-m31-eusb2.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c b/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
index 275df38256de..72fa71003fd9 100644
--- a/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
@@ -277,6 +277,8 @@ static int m31eusb2_phy_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(phy->phy),
"failed to create phy\n");
+ phy_set_type(phy->phy, PHY_TYPE_EUSB2);
+
ret = devm_regulator_bulk_get_const(dev, M31_EUSB_NUM_VREGS,
m31_eusb_phy_vregs, &phy->vregs);
if (ret)
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 5/5] usb: dwc3: qcom: Modify interrupt handling for eUSB2 Phy targets
2026-09-13 14:40 ` Krishna Kurapati
@ 2026-09-13 14:40 ` Krishna Kurapati
-1 siblings, 0 replies; 14+ messages in thread
From: Krishna Kurapati @ 2026-09-13 14:40 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thinh Nguyen,
Greg Kroah-Hartman
Cc: linux-phy, devicetree, linux-kernel, linux-arm-msm, linux-usb,
Krishna Kurapati, Konrad Dybcio
eUSB2 targets handle wakeup interrupts differently depending on device
speed when operating in host mode.
According to the eUSB2 specification, remote wakeup signaling in host
mode is detected via different data-line assertions based on the
connected device speed.
When a low-speed device is connected, the host repeater drives eD+ to
logic '1' upon detecting a K-state on the USB lines during remote wakeup
(eUSB2 specification, Section 5.5.14).
When a full-speed or high-speed device is connected, the host repeater
drives eD- to logic '1' upon detecting a K-state on the USB line during
remote wakeup (eUSB2 specification, Sections 5.5.15 and 5.5.18).
Since the eUSB2 PHY's "DP" and "DM" interrupt lines monitor the eD+ and
eD- line states, query the phy type and configure the wakeup interrupts
accordingly.
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
---
drivers/usb/dwc3/dwc3-qcom.c | 63 +++++++++++++++++++++++++++++++++-----------
1 file changed, 48 insertions(+), 15 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
index ac68b4218b56..e6b6beb38fcb 100644
--- a/drivers/usb/dwc3/dwc3-qcom.c
+++ b/drivers/usb/dwc3/dwc3-qcom.c
@@ -85,6 +85,7 @@ struct dwc3_qcom {
struct icc_path *icc_path_apps;
enum usb_role current_role;
+ bool has_eusb2_phy;
};
#define to_dwc3_qcom(d) container_of((d), struct dwc3_qcom, dwc)
@@ -272,15 +273,23 @@ static void dwc3_qcom_disable_wakeup_irq(int irq)
disable_irq_nosync(irq);
}
-static void dwc3_qcom_disable_port_interrupts(struct dwc3_qcom_port *port)
+static void dwc3_qcom_disable_port_interrupts(struct dwc3_qcom *qcom, int port_index)
{
+ struct dwc3_qcom_port *port = &qcom->ports[port_index];
+
dwc3_qcom_disable_wakeup_irq(port->qusb2_phy_irq);
if (port->usb2_speed == USB_SPEED_LOW) {
- dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);
+ if (qcom->has_eusb2_phy)
+ dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
+ else
+ dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);
} else if ((port->usb2_speed == USB_SPEED_HIGH) ||
(port->usb2_speed == USB_SPEED_FULL)) {
- dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
+ if (qcom->has_eusb2_phy)
+ dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);
+ else
+ dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
} else {
dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);
@@ -289,26 +298,38 @@ static void dwc3_qcom_disable_port_interrupts(struct dwc3_qcom_port *port)
dwc3_qcom_disable_wakeup_irq(port->ss_phy_irq);
}
-static void dwc3_qcom_enable_port_interrupts(struct dwc3_qcom_port *port)
+static void dwc3_qcom_enable_port_interrupts(struct dwc3_qcom *qcom, int port_index)
{
+ struct dwc3_qcom_port *port = &qcom->ports[port_index];
+
dwc3_qcom_enable_wakeup_irq(port->qusb2_phy_irq, 0);
/*
* Configure DP/DM line interrupts based on the USB2 device attached to
- * the root hub port. When HS/FS device is connected, configure the DP line
- * as falling edge to detect both disconnect and remote wakeup scenarios. When
- * LS device is connected, configure DM line as falling edge to detect both
- * disconnect and remote wakeup. When no device is connected, configure both
- * DP and DM lines as rising edge to detect HS/HS/LS device connect scenario.
+ * the root hub port. For non-eUSB2 targets, when HS/FS device is connected,
+ * configure the DP line as falling edge to detect disconnect and remote
+ * wakeup. When LS device is connected, configure the DM line as falling edge
+ * for the same. For eUSB2 targets, the lines are swapped and rising edge is
+ * used: DP line for LS and DM line for HS/FS device detection. When no
+ * device is connected, configure both DP and DM lines as rising edge to
+ * detect HS/FS/LS device connect scenario.
*/
if (port->usb2_speed == USB_SPEED_LOW) {
- dwc3_qcom_enable_wakeup_irq(port->dm_hs_phy_irq,
- IRQ_TYPE_EDGE_FALLING);
+ if (qcom->has_eusb2_phy)
+ dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
+ IRQ_TYPE_EDGE_RISING);
+ else
+ dwc3_qcom_enable_wakeup_irq(port->dm_hs_phy_irq,
+ IRQ_TYPE_EDGE_FALLING);
} else if ((port->usb2_speed == USB_SPEED_HIGH) ||
(port->usb2_speed == USB_SPEED_FULL)) {
- dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
- IRQ_TYPE_EDGE_FALLING);
+ if (qcom->has_eusb2_phy)
+ dwc3_qcom_enable_wakeup_irq(port->dm_hs_phy_irq,
+ IRQ_TYPE_EDGE_RISING);
+ else
+ dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
+ IRQ_TYPE_EDGE_FALLING);
} else {
dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
IRQ_TYPE_EDGE_RISING);
@@ -324,7 +345,7 @@ static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom)
int i;
for (i = 0; i < qcom->num_ports; i++)
- dwc3_qcom_disable_port_interrupts(&qcom->ports[i]);
+ dwc3_qcom_disable_port_interrupts(qcom, i);
}
static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
@@ -332,7 +353,7 @@ static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
int i;
for (i = 0; i < qcom->num_ports; i++)
- dwc3_qcom_enable_port_interrupts(&qcom->ports[i]);
+ dwc3_qcom_enable_port_interrupts(qcom, i);
}
static int dwc3_qcom_suspend(struct dwc3_qcom *qcom, bool wakeup)
@@ -617,6 +638,7 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
int ret;
bool ignore_pipe_clk;
bool wakeup_source;
+ struct phy *phy;
qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL);
if (!qcom)
@@ -683,6 +705,17 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
if (ignore_pipe_clk)
dwc3_qcom_select_utmi_clk(qcom);
+ phy = devm_of_phy_get_by_index(dev, dev->of_node, 0);
+ if (IS_ERR(phy)) {
+ if (PTR_ERR(phy) != -ENODEV) {
+ ret = dev_err_probe(dev, PTR_ERR(phy),
+ "failed to get usb2 phy\n");
+ goto clk_disable;
+ }
+ phy = NULL;
+ }
+ qcom->has_eusb2_phy = (phy_get_type(phy) == PHY_TYPE_EUSB2);
+
qcom->mode = usb_get_dr_mode(dev);
if (qcom->mode == USB_DR_MODE_HOST) {
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v8 5/5] usb: dwc3: qcom: Modify interrupt handling for eUSB2 Phy targets
@ 2026-09-13 14:40 ` Krishna Kurapati
0 siblings, 0 replies; 14+ messages in thread
From: Krishna Kurapati @ 2026-09-13 14:40 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thinh Nguyen,
Greg Kroah-Hartman
Cc: linux-phy, devicetree, linux-kernel, linux-arm-msm, linux-usb,
Krishna Kurapati, Konrad Dybcio
eUSB2 targets handle wakeup interrupts differently depending on device
speed when operating in host mode.
According to the eUSB2 specification, remote wakeup signaling in host
mode is detected via different data-line assertions based on the
connected device speed.
When a low-speed device is connected, the host repeater drives eD+ to
logic '1' upon detecting a K-state on the USB lines during remote wakeup
(eUSB2 specification, Section 5.5.14).
When a full-speed or high-speed device is connected, the host repeater
drives eD- to logic '1' upon detecting a K-state on the USB line during
remote wakeup (eUSB2 specification, Sections 5.5.15 and 5.5.18).
Since the eUSB2 PHY's "DP" and "DM" interrupt lines monitor the eD+ and
eD- line states, query the phy type and configure the wakeup interrupts
accordingly.
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
---
drivers/usb/dwc3/dwc3-qcom.c | 63 +++++++++++++++++++++++++++++++++-----------
1 file changed, 48 insertions(+), 15 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
index ac68b4218b56..e6b6beb38fcb 100644
--- a/drivers/usb/dwc3/dwc3-qcom.c
+++ b/drivers/usb/dwc3/dwc3-qcom.c
@@ -85,6 +85,7 @@ struct dwc3_qcom {
struct icc_path *icc_path_apps;
enum usb_role current_role;
+ bool has_eusb2_phy;
};
#define to_dwc3_qcom(d) container_of((d), struct dwc3_qcom, dwc)
@@ -272,15 +273,23 @@ static void dwc3_qcom_disable_wakeup_irq(int irq)
disable_irq_nosync(irq);
}
-static void dwc3_qcom_disable_port_interrupts(struct dwc3_qcom_port *port)
+static void dwc3_qcom_disable_port_interrupts(struct dwc3_qcom *qcom, int port_index)
{
+ struct dwc3_qcom_port *port = &qcom->ports[port_index];
+
dwc3_qcom_disable_wakeup_irq(port->qusb2_phy_irq);
if (port->usb2_speed == USB_SPEED_LOW) {
- dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);
+ if (qcom->has_eusb2_phy)
+ dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
+ else
+ dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);
} else if ((port->usb2_speed == USB_SPEED_HIGH) ||
(port->usb2_speed == USB_SPEED_FULL)) {
- dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
+ if (qcom->has_eusb2_phy)
+ dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);
+ else
+ dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
} else {
dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);
@@ -289,26 +298,38 @@ static void dwc3_qcom_disable_port_interrupts(struct dwc3_qcom_port *port)
dwc3_qcom_disable_wakeup_irq(port->ss_phy_irq);
}
-static void dwc3_qcom_enable_port_interrupts(struct dwc3_qcom_port *port)
+static void dwc3_qcom_enable_port_interrupts(struct dwc3_qcom *qcom, int port_index)
{
+ struct dwc3_qcom_port *port = &qcom->ports[port_index];
+
dwc3_qcom_enable_wakeup_irq(port->qusb2_phy_irq, 0);
/*
* Configure DP/DM line interrupts based on the USB2 device attached to
- * the root hub port. When HS/FS device is connected, configure the DP line
- * as falling edge to detect both disconnect and remote wakeup scenarios. When
- * LS device is connected, configure DM line as falling edge to detect both
- * disconnect and remote wakeup. When no device is connected, configure both
- * DP and DM lines as rising edge to detect HS/HS/LS device connect scenario.
+ * the root hub port. For non-eUSB2 targets, when HS/FS device is connected,
+ * configure the DP line as falling edge to detect disconnect and remote
+ * wakeup. When LS device is connected, configure the DM line as falling edge
+ * for the same. For eUSB2 targets, the lines are swapped and rising edge is
+ * used: DP line for LS and DM line for HS/FS device detection. When no
+ * device is connected, configure both DP and DM lines as rising edge to
+ * detect HS/FS/LS device connect scenario.
*/
if (port->usb2_speed == USB_SPEED_LOW) {
- dwc3_qcom_enable_wakeup_irq(port->dm_hs_phy_irq,
- IRQ_TYPE_EDGE_FALLING);
+ if (qcom->has_eusb2_phy)
+ dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
+ IRQ_TYPE_EDGE_RISING);
+ else
+ dwc3_qcom_enable_wakeup_irq(port->dm_hs_phy_irq,
+ IRQ_TYPE_EDGE_FALLING);
} else if ((port->usb2_speed == USB_SPEED_HIGH) ||
(port->usb2_speed == USB_SPEED_FULL)) {
- dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
- IRQ_TYPE_EDGE_FALLING);
+ if (qcom->has_eusb2_phy)
+ dwc3_qcom_enable_wakeup_irq(port->dm_hs_phy_irq,
+ IRQ_TYPE_EDGE_RISING);
+ else
+ dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
+ IRQ_TYPE_EDGE_FALLING);
} else {
dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
IRQ_TYPE_EDGE_RISING);
@@ -324,7 +345,7 @@ static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom)
int i;
for (i = 0; i < qcom->num_ports; i++)
- dwc3_qcom_disable_port_interrupts(&qcom->ports[i]);
+ dwc3_qcom_disable_port_interrupts(qcom, i);
}
static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
@@ -332,7 +353,7 @@ static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
int i;
for (i = 0; i < qcom->num_ports; i++)
- dwc3_qcom_enable_port_interrupts(&qcom->ports[i]);
+ dwc3_qcom_enable_port_interrupts(qcom, i);
}
static int dwc3_qcom_suspend(struct dwc3_qcom *qcom, bool wakeup)
@@ -617,6 +638,7 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
int ret;
bool ignore_pipe_clk;
bool wakeup_source;
+ struct phy *phy;
qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL);
if (!qcom)
@@ -683,6 +705,17 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
if (ignore_pipe_clk)
dwc3_qcom_select_utmi_clk(qcom);
+ phy = devm_of_phy_get_by_index(dev, dev->of_node, 0);
+ if (IS_ERR(phy)) {
+ if (PTR_ERR(phy) != -ENODEV) {
+ ret = dev_err_probe(dev, PTR_ERR(phy),
+ "failed to get usb2 phy\n");
+ goto clk_disable;
+ }
+ phy = NULL;
+ }
+ qcom->has_eusb2_phy = (phy_get_type(phy) == PHY_TYPE_EUSB2);
+
qcom->mode = usb_get_dr_mode(dev);
if (qcom->mode == USB_DR_MODE_HOST) {
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v8 5/5] usb: dwc3: qcom: Modify interrupt handling for eUSB2 Phy targets
2026-09-13 14:40 ` Krishna Kurapati
@ 2026-09-13 14:53 ` sashiko-bot
-1 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-09-13 14:53 UTC (permalink / raw)
To: Krishna Kurapati
Cc: linux-phy, olteanv, robh, devicetree, neil.armstrong, conor+dt,
vkoul
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [High] Probe fails unconditionally if CONFIG_GENERIC_PHY is disabled because the error check misses -ENOSYS.
Pre-existing issues:
- [High] Missing lock and lifecycle protection when accessing xHCI drvdata leads to NULL pointer dereference during concurrent driver unbind.
--
commit fda37af83fa24f9ca3c0472a4d6f4d45d01b3ce6
Author: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
usb: dwc3: qcom: Modify interrupt handling for eUSB2 Phy targets
This patch modifies the interrupt handling for eUSB2 PHY targets in host
mode to configure wakeup interrupts differently based on the connected device
speed. The driver now queries the PHY type and configures DP/DM edge
interrupts accordingly.
> diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
> index ac68b4218b56b..e6b6beb38fcba 100644
> --- a/drivers/usb/dwc3/dwc3-qcom.c
> +++ b/drivers/usb/dwc3/dwc3-qcom.c
[ ... ]
> @@ -683,6 +705,17 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
> if (ignore_pipe_clk)
> dwc3_qcom_select_utmi_clk(qcom);
>
> + phy = devm_of_phy_get_by_index(dev, dev->of_node, 0);
> + if (IS_ERR(phy)) {
> + if (PTR_ERR(phy) != -ENODEV) {
[Severity: High]
Will this unconditionally fail to probe when CONFIG_GENERIC_PHY is disabled?
If the kernel is built without generic PHY support, devm_of_phy_get_by_index()
returns ERR_PTR(-ENOSYS). Since this check only allows -ENODEV as a benign
error, an -ENOSYS return will cause the driver to invoke dev_err_probe() and
abort initialization.
Should this check also handle -ENOSYS to allow graceful fallback when
the PHY subsystem is disabled, similar to how the DWC3 core handles it?
(e.g., if (PTR_ERR(phy) != -ENODEV && PTR_ERR(phy) != -ENOSYS))
> + ret = dev_err_probe(dev, PTR_ERR(phy),
> + "failed to get usb2 phy\n");
> + goto clk_disable;
> + }
> + phy = NULL;
> + }
> + qcom->has_eusb2_phy = (phy_get_type(phy) == PHY_TYPE_EUSB2);
> +
> qcom->mode = usb_get_dr_mode(dev);
While reviewing the driver context, I noticed a pre-existing issue in the
surrounding codebase:
drivers/usb/dwc3/dwc3-qcom.c:dwc3_qcom_read_usb2_speed() {
...
/*
* FIXME: Fix this layering violation.
*/
hcd = platform_get_drvdata(dwc->xhci);
#ifdef CONFIG_USB
udev = usb_hub_find_child(hcd->self.root_hub, port_index + 1);
...
}
[Severity: High]
This isn't a bug introduced by this patch, but does this missing lifecycle
protection for the xHCI drvdata lead to a NULL pointer dereference?
If the child xhci-plat driver fails to probe, or if a user unbinds it via sysfs
(e.g., echo xhci-hcd > /sys/bus/platform/drivers/xhci-hcd/unbind), the driver
core calls dev_set_drvdata(dev, NULL). This releases the PM usage count and
causes the parent dwc3-qcom controller to enter runtime suspend.
When dwc3_qcom_runtime_suspend() then calls dwc3_qcom_read_usb2_speed(), it
blindly retrieves the now-NULL drvdata via platform_get_drvdata() and
immediately dereferences it when accessing hcd->self.root_hub.
Could this race condition trigger a kernel panic during a concurrent driver
unbind?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260913-eusb2-interrupt-v8-v8-0-0f505b9c394b@oss.qualcomm.com?part=5
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v8 5/5] usb: dwc3: qcom: Modify interrupt handling for eUSB2 Phy targets
@ 2026-09-13 14:53 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-09-13 14:53 UTC (permalink / raw)
To: Krishna Kurapati
Cc: linux-phy, olteanv, robh, devicetree, neil.armstrong, conor+dt,
vkoul
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [High] Probe fails unconditionally if CONFIG_GENERIC_PHY is disabled because the error check misses -ENOSYS.
Pre-existing issues:
- [High] Missing lock and lifecycle protection when accessing xHCI drvdata leads to NULL pointer dereference during concurrent driver unbind.
--
commit fda37af83fa24f9ca3c0472a4d6f4d45d01b3ce6
Author: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
usb: dwc3: qcom: Modify interrupt handling for eUSB2 Phy targets
This patch modifies the interrupt handling for eUSB2 PHY targets in host
mode to configure wakeup interrupts differently based on the connected device
speed. The driver now queries the PHY type and configures DP/DM edge
interrupts accordingly.
> diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
> index ac68b4218b56b..e6b6beb38fcba 100644
> --- a/drivers/usb/dwc3/dwc3-qcom.c
> +++ b/drivers/usb/dwc3/dwc3-qcom.c
[ ... ]
> @@ -683,6 +705,17 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
> if (ignore_pipe_clk)
> dwc3_qcom_select_utmi_clk(qcom);
>
> + phy = devm_of_phy_get_by_index(dev, dev->of_node, 0);
> + if (IS_ERR(phy)) {
> + if (PTR_ERR(phy) != -ENODEV) {
[Severity: High]
Will this unconditionally fail to probe when CONFIG_GENERIC_PHY is disabled?
If the kernel is built without generic PHY support, devm_of_phy_get_by_index()
returns ERR_PTR(-ENOSYS). Since this check only allows -ENODEV as a benign
error, an -ENOSYS return will cause the driver to invoke dev_err_probe() and
abort initialization.
Should this check also handle -ENOSYS to allow graceful fallback when
the PHY subsystem is disabled, similar to how the DWC3 core handles it?
(e.g., if (PTR_ERR(phy) != -ENODEV && PTR_ERR(phy) != -ENOSYS))
> + ret = dev_err_probe(dev, PTR_ERR(phy),
> + "failed to get usb2 phy\n");
> + goto clk_disable;
> + }
> + phy = NULL;
> + }
> + qcom->has_eusb2_phy = (phy_get_type(phy) == PHY_TYPE_EUSB2);
> +
> qcom->mode = usb_get_dr_mode(dev);
While reviewing the driver context, I noticed a pre-existing issue in the
surrounding codebase:
drivers/usb/dwc3/dwc3-qcom.c:dwc3_qcom_read_usb2_speed() {
...
/*
* FIXME: Fix this layering violation.
*/
hcd = platform_get_drvdata(dwc->xhci);
#ifdef CONFIG_USB
udev = usb_hub_find_child(hcd->self.root_hub, port_index + 1);
...
}
[Severity: High]
This isn't a bug introduced by this patch, but does this missing lifecycle
protection for the xHCI drvdata lead to a NULL pointer dereference?
If the child xhci-plat driver fails to probe, or if a user unbinds it via sysfs
(e.g., echo xhci-hcd > /sys/bus/platform/drivers/xhci-hcd/unbind), the driver
core calls dev_set_drvdata(dev, NULL). This releases the PM usage count and
causes the parent dwc3-qcom controller to enter runtime suspend.
When dwc3_qcom_runtime_suspend() then calls dwc3_qcom_read_usb2_speed(), it
blindly retrieves the now-NULL drvdata via platform_get_drvdata() and
immediately dereferences it when accessing hcd->self.root_hub.
Could this race condition trigger a kernel panic during a concurrent driver
unbind?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260913-eusb2-interrupt-v8-v8-0-0f505b9c394b@oss.qualcomm.com?part=5
^ permalink raw reply [flat|nested] 14+ messages in thread