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

net: phy: mscc: Consolidate probe functions into a common helper

Unify the probe implementations of the VSC85xx PHY family into a single
vsc85xx_probe_common() helper. The existing probe functions for the
vsc85xx, vsc8514, vsc8574, and vsc8584 variants contained almost
identical initialization logic, differing only in configuration
parameters such as the number of LEDs, supported LED modes, hardware
statistics, and PTP support.

Introduce a vsc85xx_probe_config structure to describe the per-variant
parameters, and move all common setup code into the shared helper. Each
variant's probe function now defines a constant configuration instance
and calls vsc85xx_probe_common().

Also mark the default LED mode array parameter as const to match its
usage.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/20251112135715.1017117-3-prabhakar.mahadev-lad.rj@bp.renesas.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Lad Prabhakar and committed by
Jakub Kicinski
217eb2d6 c31783c2

+112 -101
+112 -101
drivers/net/phy/mscc/mscc_main.c
··· 22 22 #include "mscc_serdes.h" 23 23 #include "mscc.h" 24 24 25 + struct vsc85xx_probe_config { 26 + const struct vsc85xx_hw_stat *hw_stats; 27 + size_t shared_size; 28 + size_t nstats; 29 + u16 supp_led_modes; 30 + u8 nleds; 31 + bool check_rate_magic; 32 + bool use_package; 33 + bool has_ptp; 34 + }; 35 + 36 + static const u32 vsc85xx_default_led_modes_4[] = { 37 + VSC8531_LINK_1000_ACTIVITY, 38 + VSC8531_LINK_100_ACTIVITY, 39 + VSC8531_LINK_ACTIVITY, 40 + VSC8531_DUPLEX_COLLISION 41 + }; 42 + 25 43 static const struct vsc85xx_hw_stat vsc85xx_hw_stats[] = { 26 44 { 27 45 .string = "phy_receive_errors", ··· 454 436 #endif /* CONFIG_OF_MDIO */ 455 437 456 438 static int vsc85xx_dt_led_modes_get(struct phy_device *phydev, 457 - u32 *default_mode) 439 + const u32 *default_mode) 458 440 { 459 441 struct vsc8531_private *priv = phydev->priv; 460 442 char led_dt_prop[28]; ··· 2229 2211 reg_val); 2230 2212 } 2231 2213 2232 - static int vsc8514_probe(struct phy_device *phydev) 2214 + static int vsc85xx_probe_common(struct phy_device *phydev, 2215 + const struct vsc85xx_probe_config *cfg, 2216 + const u32 *default_led_mode) 2233 2217 { 2234 2218 struct vsc8531_private *vsc8531; 2235 - u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY, 2236 - VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY, 2237 - VSC8531_DUPLEX_COLLISION}; 2238 - 2239 - vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL); 2240 - if (!vsc8531) 2241 - return -ENOMEM; 2242 - 2243 - phydev->priv = vsc8531; 2244 - 2245 - vsc8584_get_base_addr(phydev); 2246 - devm_phy_package_join(&phydev->mdio.dev, phydev, 2247 - vsc8531->base_addr, 0); 2248 - 2249 - vsc8531->nleds = 4; 2250 - vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES; 2251 - vsc8531->hw_stats = vsc85xx_hw_stats; 2252 - vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats); 2253 - vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, 2254 - sizeof(u64), GFP_KERNEL); 2255 - if (!vsc8531->stats) 2256 - return -ENOMEM; 2257 - 2258 - return vsc85xx_dt_led_modes_get(phydev, default_mode); 2259 - } 2260 - 2261 - static int vsc8574_probe(struct phy_device *phydev) 2262 - { 2263 - struct vsc8531_private *vsc8531; 2264 - u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY, 2265 - VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY, 2266 - VSC8531_DUPLEX_COLLISION}; 2267 - 2268 - vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL); 2269 - if (!vsc8531) 2270 - return -ENOMEM; 2271 - 2272 - phydev->priv = vsc8531; 2273 - 2274 - vsc8584_get_base_addr(phydev); 2275 - devm_phy_package_join(&phydev->mdio.dev, phydev, 2276 - vsc8531->base_addr, 0); 2277 - 2278 - vsc8531->nleds = 4; 2279 - vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES; 2280 - vsc8531->hw_stats = vsc8584_hw_stats; 2281 - vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats); 2282 - vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, 2283 - sizeof(u64), GFP_KERNEL); 2284 - if (!vsc8531->stats) 2285 - return -ENOMEM; 2286 - 2287 - return vsc85xx_dt_led_modes_get(phydev, default_mode); 2288 - } 2289 - 2290 - static int vsc8584_probe(struct phy_device *phydev) 2291 - { 2292 - struct vsc8531_private *vsc8531; 2293 - u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY, 2294 - VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY, 2295 - VSC8531_DUPLEX_COLLISION}; 2296 2219 int ret; 2297 2220 2298 2221 vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL); ··· 2242 2283 2243 2284 phydev->priv = vsc8531; 2244 2285 2245 - vsc8584_get_base_addr(phydev); 2246 - devm_phy_package_join(&phydev->mdio.dev, phydev, vsc8531->base_addr, 2247 - sizeof(struct vsc85xx_shared_private)); 2286 + /* Check rate magic if needed (only for non-package PHYs) */ 2287 + if (cfg->check_rate_magic) { 2288 + ret = vsc85xx_edge_rate_magic_get(phydev); 2289 + if (ret < 0) 2290 + return ret; 2248 2291 2249 - vsc8531->nleds = 4; 2250 - vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES; 2251 - vsc8531->hw_stats = vsc8584_hw_stats; 2252 - vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats); 2292 + vsc8531->rate_magic = ret; 2293 + } 2294 + 2295 + /* Set up package if needed */ 2296 + if (cfg->use_package) { 2297 + vsc8584_get_base_addr(phydev); 2298 + devm_phy_package_join(&phydev->mdio.dev, phydev, 2299 + vsc8531->base_addr, cfg->shared_size); 2300 + } 2301 + 2302 + /* Configure LED settings */ 2303 + vsc8531->nleds = cfg->nleds; 2304 + vsc8531->supp_led_modes = cfg->supp_led_modes; 2305 + 2306 + /* Configure hardware stats */ 2307 + vsc8531->hw_stats = cfg->hw_stats; 2308 + vsc8531->nstats = cfg->nstats; 2253 2309 vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, 2254 2310 sizeof(u64), GFP_KERNEL); 2255 2311 if (!vsc8531->stats) 2256 2312 return -ENOMEM; 2257 2313 2258 - if (phy_package_probe_once(phydev)) { 2259 - ret = vsc8584_ptp_probe_once(phydev); 2314 + /* PTP setup for VSC8584 */ 2315 + if (cfg->has_ptp) { 2316 + if (phy_package_probe_once(phydev)) { 2317 + ret = vsc8584_ptp_probe_once(phydev); 2318 + if (ret) 2319 + return ret; 2320 + } 2321 + 2322 + ret = vsc8584_ptp_probe(phydev); 2260 2323 if (ret) 2261 2324 return ret; 2262 2325 } 2263 2326 2264 - ret = vsc8584_ptp_probe(phydev); 2265 - if (ret) 2266 - return ret; 2327 + /* Parse LED modes from device tree */ 2328 + return vsc85xx_dt_led_modes_get(phydev, default_led_mode); 2329 + } 2267 2330 2268 - return vsc85xx_dt_led_modes_get(phydev, default_mode); 2331 + static int vsc8514_probe(struct phy_device *phydev) 2332 + { 2333 + static const struct vsc85xx_probe_config vsc8514_cfg = { 2334 + .nleds = 4, 2335 + .supp_led_modes = VSC85XX_SUPP_LED_MODES, 2336 + .hw_stats = vsc85xx_hw_stats, 2337 + .nstats = ARRAY_SIZE(vsc85xx_hw_stats), 2338 + .use_package = true, 2339 + .shared_size = 0, 2340 + .has_ptp = false, 2341 + .check_rate_magic = false, 2342 + }; 2343 + 2344 + return vsc85xx_probe_common(phydev, &vsc8514_cfg, vsc85xx_default_led_modes_4); 2345 + } 2346 + 2347 + static int vsc8574_probe(struct phy_device *phydev) 2348 + { 2349 + static const struct vsc85xx_probe_config vsc8574_cfg = { 2350 + .nleds = 4, 2351 + .supp_led_modes = VSC8584_SUPP_LED_MODES, 2352 + .hw_stats = vsc8584_hw_stats, 2353 + .nstats = ARRAY_SIZE(vsc8584_hw_stats), 2354 + .use_package = true, 2355 + .shared_size = 0, 2356 + .has_ptp = false, 2357 + .check_rate_magic = false, 2358 + }; 2359 + 2360 + return vsc85xx_probe_common(phydev, &vsc8574_cfg, vsc85xx_default_led_modes_4); 2361 + } 2362 + 2363 + static int vsc8584_probe(struct phy_device *phydev) 2364 + { 2365 + static const struct vsc85xx_probe_config vsc8584_cfg = { 2366 + .nleds = 4, 2367 + .supp_led_modes = VSC8584_SUPP_LED_MODES, 2368 + .hw_stats = vsc8584_hw_stats, 2369 + .nstats = ARRAY_SIZE(vsc8584_hw_stats), 2370 + .use_package = true, 2371 + .shared_size = sizeof(struct vsc85xx_shared_private), 2372 + .has_ptp = true, 2373 + .check_rate_magic = false, 2374 + }; 2375 + 2376 + return vsc85xx_probe_common(phydev, &vsc8584_cfg, vsc85xx_default_led_modes_4); 2269 2377 } 2270 2378 2271 2379 static int vsc85xx_probe(struct phy_device *phydev) 2272 2380 { 2273 - struct vsc8531_private *vsc8531; 2274 - int rate_magic; 2275 - u32 default_mode[2] = {VSC8531_LINK_1000_ACTIVITY, 2276 - VSC8531_LINK_100_ACTIVITY}; 2381 + static const struct vsc85xx_probe_config vsc85xx_cfg = { 2382 + .nleds = 2, 2383 + .supp_led_modes = VSC85XX_SUPP_LED_MODES, 2384 + .hw_stats = vsc85xx_hw_stats, 2385 + .nstats = ARRAY_SIZE(vsc85xx_hw_stats), 2386 + .use_package = false, 2387 + .has_ptp = false, 2388 + .check_rate_magic = true, 2389 + }; 2277 2390 2278 - rate_magic = vsc85xx_edge_rate_magic_get(phydev); 2279 - if (rate_magic < 0) 2280 - return rate_magic; 2281 - 2282 - vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL); 2283 - if (!vsc8531) 2284 - return -ENOMEM; 2285 - 2286 - phydev->priv = vsc8531; 2287 - 2288 - vsc8531->rate_magic = rate_magic; 2289 - vsc8531->nleds = 2; 2290 - vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES; 2291 - vsc8531->hw_stats = vsc85xx_hw_stats; 2292 - vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats); 2293 - vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, 2294 - sizeof(u64), GFP_KERNEL); 2295 - if (!vsc8531->stats) 2296 - return -ENOMEM; 2297 - 2298 - return vsc85xx_dt_led_modes_get(phydev, default_mode); 2391 + return vsc85xx_probe_common(phydev, &vsc85xx_cfg, vsc85xx_default_led_modes_4); 2299 2392 } 2300 2393 2301 2394 static void vsc85xx_remove(struct phy_device *phydev)