From 14639bf14d824d9fbcfd918f0e7924c7f7065422 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Thu, 31 Aug 2023 22:16:35 +0000 Subject: [PATCH] phy: Set phy->dev to NULL when generic_phy_get_by_index_nodev() fails 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 --- 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 b48456aebe..63fda15da7 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -433,6 +433,11 @@ #phy-cells = <0>; }; + phy_provider3: gen_phy@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>; @@ -445,6 +450,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 0baf314a34..7d707c0229 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 09329b9f71..2abd27b22d 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.39.5