ac4c44a7205aae0ca2007a5f0cd14d31ce5a4304
[openwrt/staging/xback.git] /
1 From 5b2f02ccca7b9496f0a8da6ade063b82810c75e7 Mon Sep 17 00:00:00 2001
2 From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
3 Date: Mon, 12 May 2025 09:27:17 -0500
4 Subject: [PATCH] net: pcs: qcom-ipq9574: delay mii clock probing until
5 ipq_pcs_get()
6
7 NSSCC generates the SYS and AHB clocks for the PCS block The PCS then
8 feeds the uniphy clocks back to the NSSCC, which are in turn, used to
9 feed the PCS MII clocks. This works fine in hardware:
10
11 GCC -> NSSCC -> PCS -> NSSCC -> PCS(MII)
12
13 However, when the PCS MII clocks are probed within the .probe() of
14 the PCS block, it creates a circular dependency. The MII clocks depend
15 on the uniphy clocks, which depend on the PCS block being probed.
16 Since we are in the process of probing the PCS block, this results in
17 both blocks returning with -EPROBE_DEFER:
18
19 platform 39b00000.clock-controller: deferred probe pending: platform: supplier 7a00000.ethernet-pcs not ready
20 mdio_bus 90000.mdio-1:18: deferred probe pending: mdio_bus: supplier 7a20000.ethernet-pcs not ready
21 mdio_bus 90000.mdio-1:00: deferred probe pending: mdio_bus: supplier 90000.mdio-1:18 not ready
22 mdio_bus 90000.mdio-1:01: deferred probe pending: mdio_bus: supplier 90000.mdio-1:18 not ready
23 mdio_bus 90000.mdio-1:02: deferred probe pending: mdio_bus: supplier 90000.mdio-1:18 not ready
24 mdio_bus 90000.mdio-1:03: deferred probe pending: mdio_bus: supplier 90000.mdio-1:18 not ready
25 platform 7a00000.ethernet-pcs: deferred probe pending: ipq9574_pcs: Failed to get MII 0 RX clock
26 platform 7a20000.ethernet-pcs: deferred probe pending: ipq9574_pcs: Failed to get MII 0 RX clock
27 platform 3a000000.qcom-ppe: deferred probe pending: platform: supplier 39b00000.clock-controller not ready
28
29 To break this dependency, let the PCS block probe, and only probe the
30 PCS MII clocks from ipq_pcs_get().
31
32 Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
33 ---
34 drivers/net/pcs/pcs-qcom-ipq9574.c | 30 ++++++++++++++++--------------
35 1 file changed, 16 insertions(+), 14 deletions(-)
36
37 --- a/drivers/net/pcs/pcs-qcom-ipq9574.c
38 +++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
39 @@ -580,20 +580,6 @@ static int ipq_pcs_create_miis(struct ip
40 qpcs_mii->pcs.neg_mode = true;
41 qpcs_mii->pcs.poll = true;
42
43 - qpcs_mii->rx_clk = devm_get_clk_from_child(dev, mii_np, "rx");
44 - if (IS_ERR(qpcs_mii->rx_clk)) {
45 - of_node_put(mii_np);
46 - return dev_err_probe(dev, PTR_ERR(qpcs_mii->rx_clk),
47 - "Failed to get MII %d RX clock\n", index);
48 - }
49 -
50 - qpcs_mii->tx_clk = devm_get_clk_from_child(dev, mii_np, "tx");
51 - if (IS_ERR(qpcs_mii->tx_clk)) {
52 - of_node_put(mii_np);
53 - return dev_err_probe(dev, PTR_ERR(qpcs_mii->tx_clk),
54 - "Failed to get MII %d TX clock\n", index);
55 - }
56 -
57 qpcs->qpcs_mii[index] = qpcs_mii;
58 }
59
60 @@ -848,6 +834,22 @@ struct phylink_pcs *ipq_pcs_get(struct d
61 return ERR_PTR(-ENOENT);
62 }
63
64 + qpcs_mii->rx_clk = devm_get_clk_from_child(&pdev->dev, np, "rx");
65 + if (IS_ERR(qpcs_mii->rx_clk)) {
66 + put_device(&pdev->dev);
67 + return dev_err_ptr_probe(&pdev->dev, PTR_ERR(qpcs_mii->rx_clk),
68 + "Failed to get MII %d RX clock\n",
69 + index);
70 + }
71 +
72 + qpcs_mii->tx_clk = devm_get_clk_from_child(&pdev->dev, np, "tx");
73 + if (IS_ERR(qpcs_mii->tx_clk)) {
74 + put_device(&pdev->dev);
75 + return dev_err_ptr_probe(&pdev->dev, PTR_ERR(qpcs_mii->tx_clk),
76 + "Failed to get MII %d TX clock\n",
77 + index);
78 + }
79 +
80 return &qpcs_mii->pcs;
81 }
82 EXPORT_SYMBOL(ipq_pcs_get);