]> git.ipfire.org Git - thirdparty/openwrt.git/blob
6750fdb2efdd1093d908a07499df7a98f14ade2c
[thirdparty/openwrt.git] /
1 From 9408076fd9e4d41876af41523cad9bfa77b3a557 Mon Sep 17 00:00:00 2001
2 From: Christian Marangi <ansuelsmth@gmail.com>
3 Date: Thu, 30 Jan 2025 16:11:14 +0100
4 Subject: [PATCH 2/3] clk: qcom: nsscc: Attach required NSSNOC clock to PM
5 domain
6
7 There is currently a problem with ICC clock disabling the NSSNOC clock
8 as there isn't any user for them on calling sync_state.
9 This cause the kernel to stall if NSS is enabled and reboot with the watchdog.
10
11 This is caused by the fact that the NSSNOC clock nsscc, snoc and snoc_1
12 are actually required to make the NSS work and make the system continue
13 booting.
14
15 To attach these clock, setup pm-clk in nsscc and setup the correct
16 resume/suspend OPs.
17
18 With this change, the clock gets correctly attached and are not disabled
19 when ICC call the sync_state.
20
21 Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
22 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
23 ---
24 drivers/clk/qcom/nsscc-ipq9574.c | 49 +++++++++++++++++++++++++++++++-
25 1 file changed, 48 insertions(+), 1 deletion(-)
26
27 --- a/drivers/clk/qcom/nsscc-ipq9574.c
28 +++ b/drivers/clk/qcom/nsscc-ipq9574.c
29 @@ -12,6 +12,8 @@
30 #include <linux/module.h>
31 #include <linux/of.h>
32 #include <linux/of_device.h>
33 +#include <linux/pm_clock.h>
34 +#include <linux/pm_runtime.h>
35 #include <linux/regmap.h>
36 #include <linux/platform_device.h>
37
38 @@ -41,6 +43,9 @@ enum {
39 DT_UNIPHY1_NSS_TX_CLK,
40 DT_UNIPHY2_NSS_RX_CLK,
41 DT_UNIPHY2_NSS_TX_CLK,
42 + DT_GCC_NSSNOC_NSSCC_CLK,
43 + DT_GCC_NSSNOC_SNOC_CLK,
44 + DT_GCC_NSSNOC_SNOC_1_CLK,
45 };
46
47 enum {
48 @@ -3046,6 +3051,10 @@ static const struct qcom_cc_desc nss_cc_
49 .icc_first_node_id = IPQ_NSSCC_ID,
50 };
51
52 +static const struct dev_pm_ops nsscc_pm_ops = {
53 + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
54 +};
55 +
56 static const struct of_device_id nss_cc_ipq9574_match_table[] = {
57 { .compatible = "qcom,ipq9574-nsscc" },
58 { }
59 @@ -3054,7 +3063,33 @@ MODULE_DEVICE_TABLE(of, nss_cc_ipq9574_m
60
61 static int nss_cc_ipq9574_probe(struct platform_device *pdev)
62 {
63 + struct device *dev = &pdev->dev;
64 struct regmap *regmap;
65 + int ret;
66 +
67 + ret = devm_pm_runtime_enable(dev);
68 + if (ret)
69 + return ret;
70 +
71 + ret = devm_pm_clk_create(dev);
72 + if (ret)
73 + return ret;
74 +
75 + ret = of_pm_clk_add_clk_index(dev, DT_GCC_NSSNOC_NSSCC_CLK);
76 + if (ret)
77 + return dev_err_probe(dev, ret,"failed to acquire nssnoc clock\n");
78 +
79 + ret = of_pm_clk_add_clk_index(dev, DT_GCC_NSSNOC_SNOC_CLK);
80 + if (ret)
81 + return dev_err_probe(dev, ret,"failed to acquire snoc clock\n");
82 +
83 + ret = of_pm_clk_add_clk_index(dev, DT_GCC_NSSNOC_SNOC_1_CLK);
84 + if (ret)
85 + return dev_err_probe(dev, ret,"failed to acquire snoc_1 clock\n");
86 +
87 + ret = pm_runtime_resume_and_get(dev);
88 + if (ret)
89 + return ret;
90
91 regmap = qcom_cc_map(pdev, &nss_cc_ipq9574_desc);
92 if (IS_ERR(regmap))
93 @@ -3062,7 +3097,18 @@ static int nss_cc_ipq9574_probe(struct p
94
95 clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
96
97 - return qcom_cc_really_probe(&pdev->dev, &nss_cc_ipq9574_desc, regmap);
98 + ret = qcom_cc_really_probe(dev, &nss_cc_ipq9574_desc, regmap);
99 + if (ret)
100 + goto err_put_pm;
101 +
102 + pm_runtime_put(dev);
103 +
104 + return 0;
105 +
106 +err_put_pm:
107 + pm_runtime_put_sync(dev);
108 +
109 + return ret;
110 }
111
112 static struct platform_driver nss_cc_ipq9574_driver = {
113 @@ -3071,6 +3117,7 @@ static struct platform_driver nss_cc_ipq
114 .name = "qcom,nsscc-ipq9574",
115 .of_match_table = nss_cc_ipq9574_match_table,
116 .sync_state = icc_sync_state,
117 + .pm = &nsscc_pm_ops,
118 },
119 };
120