Skip to content

Commit 75c2141

Browse files
Andre-ARMvinodkoul
authored andcommitted
phy: sun4i-usb: drop num_phys assumption
So far we set a number of expected Allwinner USB PHY instances for any given compatible string, and would fail if we do not find every PHY described properly in the DT (missing reset/PMU/clocks). This is somewhat redundant, as the DT only describes the resources for the implemented PHYs, but goes in line with being strict about firmware descriptions, and rather fixing things in the driver code, based on the compatible string. However this causes issues when we make a mistake, like we did recently on the A523: there are actually three USB PHYs, not two, as we assumed. Changing the number in the driver and the compatible string would cause all kinds of compatibility issues, both with older and newer DTs. To avoid problems with newer kernels and older or newer DTs, we can change the driver code to deduce the number of PHY instances from what's described in the DT. This has the added advantage of not requiring new compatible strings for new SoCs when just the number of PHYs change, which already happened and might occur again in the future. Drop the num_phys member from the config struct, and remove the fixed number of PHYs from each SoC's config description. Then enumerate the usb<x>_reset properties for all of the maximum four PHY instances, and just stop once we cannot find such a property anymore. The binding describes the reset property as mandatory for each PHY instance, and each DT in the kernel tree matches exactly the num_phys value in the current driver code, so we can rely on that. Apart from being more future proof, this will solve the A523 mishap: Older DTs would just describe two PHYs, whereas newer ones would feature all three of them. In any case we would get a valid number, matching the other nodes in the DT. Older kernels would always enumerate two PHYs, which at least does not cause any regressions. Signed-off-by: Andre Przywara <andre.przywara@arm.com> Link: https://lore.kernel.org/r/20250819001522.13011-1-andre.przywara@arm.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent 0f05174 commit 75c2141

1 file changed

Lines changed: 13 additions & 25 deletions

File tree

drivers/phy/allwinner/phy-sun4i-usb.c

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@
9797
#define POLL_TIME msecs_to_jiffies(250)
9898

9999
struct sun4i_usb_phy_cfg {
100-
int num_phys;
101100
int hsic_index;
102101
u32 disc_thresh;
103102
u32 hci_phy_ctl_clear;
@@ -115,6 +114,7 @@ struct sun4i_usb_phy_data {
115114
const struct sun4i_usb_phy_cfg *cfg;
116115
enum usb_dr_mode dr_mode;
117116
spinlock_t reg_lock; /* guard access to phyctl reg */
117+
int num_phys;
118118
struct sun4i_usb_phy {
119119
struct phy *phy;
120120
void __iomem *pmu;
@@ -686,7 +686,7 @@ static struct phy *sun4i_usb_phy_xlate(struct device *dev,
686686
{
687687
struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
688688

689-
if (args->args[0] >= data->cfg->num_phys)
689+
if (args->args[0] >= data->num_phys)
690690
return ERR_PTR(-ENODEV);
691691

692692
if (data->cfg->missing_phys & BIT(args->args[0]))
@@ -779,13 +779,22 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
779779
return ret;
780780
}
781781

782-
for (i = 0; i < data->cfg->num_phys; i++) {
782+
for (i = 0; i < MAX_PHYS; i++) {
783783
struct sun4i_usb_phy *phy = data->phys + i;
784784
char name[32];
785785

786786
if (data->cfg->missing_phys & BIT(i))
787787
continue;
788788

789+
snprintf(name, sizeof(name), "usb%d_reset", i);
790+
phy->reset = devm_reset_control_get(dev, name);
791+
if (IS_ERR(phy->reset)) {
792+
if (PTR_ERR(phy->reset) == -ENOENT)
793+
break;
794+
dev_err(dev, "failed to get reset %s\n", name);
795+
return PTR_ERR(phy->reset);
796+
}
797+
789798
snprintf(name, sizeof(name), "usb%d_vbus", i);
790799
phy->vbus = devm_regulator_get_optional(dev, name);
791800
if (IS_ERR(phy->vbus)) {
@@ -828,13 +837,6 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
828837
}
829838
}
830839

831-
snprintf(name, sizeof(name), "usb%d_reset", i);
832-
phy->reset = devm_reset_control_get(dev, name);
833-
if (IS_ERR(phy->reset)) {
834-
dev_err(dev, "failed to get reset %s\n", name);
835-
return PTR_ERR(phy->reset);
836-
}
837-
838840
if (i || data->cfg->phy0_dual_route) { /* No pmu for musb */
839841
snprintf(name, sizeof(name), "pmu%d", i);
840842
phy->pmu = devm_platform_ioremap_resource_byname(pdev, name);
@@ -851,6 +853,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
851853
phy->index = i;
852854
phy_set_drvdata(phy->phy, &data->phys[i]);
853855
}
856+
data->num_phys = i;
854857

855858
data->id_det_irq = gpiod_to_irq(data->id_det_gpio);
856859
if (data->id_det_irq > 0) {
@@ -901,67 +904,58 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
901904
}
902905

903906
static const struct sun4i_usb_phy_cfg suniv_f1c100s_cfg = {
904-
.num_phys = 1,
905907
.disc_thresh = 3,
906908
.phyctl_offset = REG_PHYCTL_A10,
907909
.dedicated_clocks = true,
908910
};
909911

910912
static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = {
911-
.num_phys = 3,
912913
.disc_thresh = 3,
913914
.phyctl_offset = REG_PHYCTL_A10,
914915
.dedicated_clocks = false,
915916
};
916917

917918
static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = {
918-
.num_phys = 2,
919919
.disc_thresh = 2,
920920
.phyctl_offset = REG_PHYCTL_A10,
921921
.dedicated_clocks = false,
922922
};
923923

924924
static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = {
925-
.num_phys = 3,
926925
.disc_thresh = 3,
927926
.phyctl_offset = REG_PHYCTL_A10,
928927
.dedicated_clocks = true,
929928
.poll_vbusen = true,
930929
};
931930

932931
static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = {
933-
.num_phys = 3,
934932
.disc_thresh = 2,
935933
.phyctl_offset = REG_PHYCTL_A10,
936934
.dedicated_clocks = false,
937935
};
938936

939937
static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = {
940-
.num_phys = 2,
941938
.disc_thresh = 3,
942939
.phyctl_offset = REG_PHYCTL_A10,
943940
.dedicated_clocks = true,
944941
.poll_vbusen = true,
945942
};
946943

947944
static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = {
948-
.num_phys = 2,
949945
.disc_thresh = 3,
950946
.phyctl_offset = REG_PHYCTL_A33,
951947
.dedicated_clocks = true,
952948
.poll_vbusen = true,
953949
};
954950

955951
static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = {
956-
.num_phys = 3,
957952
.hsic_index = 2,
958953
.phyctl_offset = REG_PHYCTL_A33,
959954
.dedicated_clocks = true,
960955
.siddq_in_base = true,
961956
};
962957

963958
static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
964-
.num_phys = 4,
965959
.disc_thresh = 3,
966960
.phyctl_offset = REG_PHYCTL_A33,
967961
.dedicated_clocks = true,
@@ -970,7 +964,6 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
970964
};
971965

972966
static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
973-
.num_phys = 3,
974967
.disc_thresh = 3,
975968
.phyctl_offset = REG_PHYCTL_A33,
976969
.dedicated_clocks = true,
@@ -979,7 +972,6 @@ static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
979972
};
980973

981974
static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
982-
.num_phys = 1,
983975
.disc_thresh = 3,
984976
.phyctl_offset = REG_PHYCTL_A33,
985977
.dedicated_clocks = true,
@@ -988,7 +980,6 @@ static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
988980
};
989981

990982
static const struct sun4i_usb_phy_cfg sun20i_d1_cfg = {
991-
.num_phys = 2,
992983
.phyctl_offset = REG_PHYCTL_A33,
993984
.dedicated_clocks = true,
994985
.hci_phy_ctl_clear = PHY_CTL_SIDDQ,
@@ -997,7 +988,6 @@ static const struct sun4i_usb_phy_cfg sun20i_d1_cfg = {
997988
};
998989

999990
static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
1000-
.num_phys = 2,
1001991
.disc_thresh = 3,
1002992
.phyctl_offset = REG_PHYCTL_A33,
1003993
.dedicated_clocks = true,
@@ -1006,7 +996,6 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
1006996
};
1007997

1008998
static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
1009-
.num_phys = 4,
1010999
.phyctl_offset = REG_PHYCTL_A33,
10111000
.dedicated_clocks = true,
10121001
.phy0_dual_route = true,
@@ -1015,7 +1004,6 @@ static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
10151004
};
10161005

10171006
static const struct sun4i_usb_phy_cfg sun50i_h616_cfg = {
1018-
.num_phys = 4,
10191007
.disc_thresh = 3,
10201008
.phyctl_offset = REG_PHYCTL_A33,
10211009
.dedicated_clocks = true,

0 commit comments

Comments
 (0)