Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phy: phy-rockchip-samsung-hdptx: Don't use dt aliases to determine phy-id

The phy needs to know its identity in the system (phy0 or phy1 on rk3588)
for some actions and the driver currently contains code abusing of_alias
for that.

Devicetree aliases are always optional and should not be used for core
device functionality, so instead keep a list of phys on a soc in the
of_device_data and find the phy-id by comparing against the mapped
register-base.

Fixes: c4b09c562086 ("phy: phy-rockchip-samsung-hdptx: Add clock provider support")
Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://lore.kernel.org/r/20241206103401.1780416-3-heiko@sntech.de
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Heiko Stuebner and committed by
Vinod Koul
f08d1c08 c8f7d65c

+44 -6
+44 -6
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
··· 263 263 RST_MAX 264 264 }; 265 265 266 + #define MAX_HDPTX_PHY_NUM 2 267 + 268 + struct rk_hdptx_phy_cfg { 269 + unsigned int num_phys; 270 + unsigned int phy_ids[MAX_HDPTX_PHY_NUM]; 271 + }; 272 + 266 273 struct rk_hdptx_phy { 267 274 struct device *dev; 268 275 struct regmap *regmap; 269 276 struct regmap *grf; 277 + 278 + /* PHY const config */ 279 + const struct rk_hdptx_phy_cfg *cfgs; 280 + int phy_id; 270 281 271 282 struct phy *phy; 272 283 struct phy_config *phy_cfg; ··· 1018 1007 struct device *dev = hdptx->dev; 1019 1008 const char *name, *pname; 1020 1009 struct clk *refclk; 1021 - int ret, id; 1010 + int ret; 1022 1011 1023 1012 refclk = devm_clk_get(dev, "ref"); 1024 1013 if (IS_ERR(refclk)) 1025 1014 return dev_err_probe(dev, PTR_ERR(refclk), 1026 1015 "Failed to get ref clock\n"); 1027 1016 1028 - id = of_alias_get_id(dev->of_node, "hdptxphy"); 1029 - name = id > 0 ? "clk_hdmiphy_pixel1" : "clk_hdmiphy_pixel0"; 1017 + name = hdptx->phy_id > 0 ? "clk_hdmiphy_pixel1" : "clk_hdmiphy_pixel0"; 1030 1018 pname = __clk_get_name(refclk); 1031 1019 1032 1020 hdptx->hw.init = CLK_HW_INIT(name, pname, &hdptx_phy_clk_ops, ··· 1068 1058 struct phy_provider *phy_provider; 1069 1059 struct device *dev = &pdev->dev; 1070 1060 struct rk_hdptx_phy *hdptx; 1061 + struct resource *res; 1071 1062 void __iomem *regs; 1072 - int ret; 1063 + int ret, id; 1073 1064 1074 1065 hdptx = devm_kzalloc(dev, sizeof(*hdptx), GFP_KERNEL); 1075 1066 if (!hdptx) ··· 1078 1067 1079 1068 hdptx->dev = dev; 1080 1069 1081 - regs = devm_platform_ioremap_resource(pdev, 0); 1070 + regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 1082 1071 if (IS_ERR(regs)) 1083 1072 return dev_err_probe(dev, PTR_ERR(regs), 1084 1073 "Failed to ioremap resource\n"); 1074 + 1075 + hdptx->cfgs = device_get_match_data(dev); 1076 + if (!hdptx->cfgs) 1077 + return dev_err_probe(dev, -EINVAL, "missing match data\n"); 1078 + 1079 + /* find the phy-id from the io address */ 1080 + hdptx->phy_id = -ENODEV; 1081 + for (id = 0; id < hdptx->cfgs->num_phys; id++) { 1082 + if (res->start == hdptx->cfgs->phy_ids[id]) { 1083 + hdptx->phy_id = id; 1084 + break; 1085 + } 1086 + } 1087 + 1088 + if (hdptx->phy_id < 0) 1089 + return dev_err_probe(dev, -ENODEV, "no matching device found\n"); 1085 1090 1086 1091 ret = devm_clk_bulk_get_all(dev, &hdptx->clks); 1087 1092 if (ret < 0) ··· 1159 1132 rk_hdptx_phy_runtime_resume, NULL) 1160 1133 }; 1161 1134 1135 + static const struct rk_hdptx_phy_cfg rk3588_hdptx_phy_cfgs = { 1136 + .num_phys = 2, 1137 + .phy_ids = { 1138 + 0xfed60000, 1139 + 0xfed70000, 1140 + }, 1141 + }; 1142 + 1162 1143 static const struct of_device_id rk_hdptx_phy_of_match[] = { 1163 - { .compatible = "rockchip,rk3588-hdptx-phy", }, 1144 + { 1145 + .compatible = "rockchip,rk3588-hdptx-phy", 1146 + .data = &rk3588_hdptx_phy_cfgs 1147 + }, 1164 1148 {} 1165 1149 }; 1166 1150 MODULE_DEVICE_TABLE(of, rk_hdptx_phy_of_match);