[PATCH 2/6] phy: Set phy->dev to NULL when generic_phy_get_by_index_nodev() fails

Jonas Karlman jonas at kwiboo.se
Fri Sep 1 00:16:35 CEST 2023


Generic phy helpers typically use generic_phy_valid() to determine if
the helper should perform its function on a passed struct phy.
generic_phy_valid() treat any struct phy having phy->dev set as valid.

With generic_phy_get_by_index_nodev() setting phy->dev to a valid struct
udevice early, there can be situations where the struct phy is returned
as valid when initialization in fact failed and returned an error.

Fix this by setting phy->dev back to NULL when any of the calls to
of_xlate ops, device_get_supply_regulator or phy_alloc_counts fail. Also
extend the dm_test_phy_base test with a test where of_xlate ops fail.

Fixes: 72e5016f878d ("drivers: phy: add generic PHY framework")
Fixes: b9688df3cbf4 ("drivers: phy: Set phy->dev to NULL when generic_phy_get_by_index() fails")
Signed-off-by: Jonas Karlman <jonas at kwiboo.se>
---
 arch/sandbox/dts/test.dts | 11 +++++++++++
 drivers/phy/phy-uclass.c  |  1 +
 test/dm/phy.c             | 12 +++++++++++-
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index f351d5cb84b0..6be212403473 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -431,6 +431,11 @@
 		#phy-cells = <0>;
 	};
 
+	phy_provider3: gen_phy at 3 {
+		compatible = "sandbox,phy";
+		#phy-cells = <2>;
+	};
+
 	gen_phy_user: gen_phy_user {
 		compatible = "simple-bus";
 		phys = <&phy_provider0 0>, <&phy_provider0 1>, <&phy_provider1>;
@@ -443,6 +448,12 @@
 		phy-names = "phy1", "phy2";
 	};
 
+	gen_phy_user2: gen_phy_user2 {
+		compatible = "simple-bus";
+		phys = <&phy_provider3 0 0>;
+		phy-names = "phy1";
+	};
+
 	some-bus {
 		#address-cells = <1>;
 		#size-cells = <0>;
diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c
index 0baf314a3471..7d707c022934 100644
--- a/drivers/phy/phy-uclass.c
+++ b/drivers/phy/phy-uclass.c
@@ -195,6 +195,7 @@ int generic_phy_get_by_index_nodev(ofnode node, int index, struct phy *phy)
 	return 0;
 
 err:
+	phy->dev = NULL;
 	return ret;
 }
 
diff --git a/test/dm/phy.c b/test/dm/phy.c
index 09329b9f71f6..2abd27b22d6d 100644
--- a/test/dm/phy.c
+++ b/test/dm/phy.c
@@ -49,7 +49,7 @@ static int dm_test_phy_base(struct unit_test_state *uts)
 	ut_assert(phy2.dev != phy3.dev);
 
 	/* Try to get a non-existing phy */
-	ut_asserteq(-ENODEV, uclass_get_device(UCLASS_PHY, 4, &dev));
+	ut_asserteq(-ENODEV, uclass_get_device(UCLASS_PHY, 5, &dev));
 	ut_asserteq(-ENODATA, generic_phy_get_by_name(parent,
 					"phy_not_existing", &phy1_method1));
 	ut_assert(!generic_phy_valid(&phy1_method1));
@@ -57,6 +57,16 @@ static int dm_test_phy_base(struct unit_test_state *uts)
 						      &phy1_method2));
 	ut_assert(!generic_phy_valid(&phy1_method2));
 
+	/* Try to get a phy where of_xlate fail */
+	ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS,
+					      "gen_phy_user2", &parent));
+	ut_asserteq(-EINVAL, generic_phy_get_by_name(parent, "phy1",
+						     &phy1_method1));
+	ut_assert(!generic_phy_valid(&phy1_method1));
+	ut_asserteq(-EINVAL, generic_phy_get_by_index(parent, 0,
+						      &phy1_method2));
+	ut_assert(!generic_phy_valid(&phy1_method2));
+
 	return 0;
 }
 DM_TEST(dm_test_phy_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
-- 
2.42.0



More information about the U-Boot mailing list