hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
....@@ -68,29 +68,61 @@
6868 /**
6969 * struct qcom_snps_hsphy - snps hs phy attributes
7070 *
71
+ * @dev: device structure
72
+ *
7173 * @phy: generic phy
7274 * @base: iomapped memory space for snps hs phy
7375 *
74
- * @cfg_ahb_clk: AHB2PHY interface clock
75
- * @ref_clk: phy reference clock
76
- * @iface_clk: phy interface clock
76
+ * @num_clks: number of clocks
77
+ * @clks: array of clocks
7778 * @phy_reset: phy reset control
7879 * @vregs: regulator supplies bulk data
7980 * @phy_initialized: if PHY has been initialized correctly
8081 * @mode: contains the current mode the PHY is in
82
+ * @update_seq_cfg: tuning parameters for phy init
8183 */
8284 struct qcom_snps_hsphy {
85
+ struct device *dev;
86
+
8387 struct phy *phy;
8488 void __iomem *base;
8589
86
- struct clk *cfg_ahb_clk;
87
- struct clk *ref_clk;
90
+ int num_clks;
91
+ struct clk_bulk_data *clks;
8892 struct reset_control *phy_reset;
8993 struct regulator_bulk_data vregs[SNPS_HS_NUM_VREGS];
9094
9195 bool phy_initialized;
9296 enum phy_mode mode;
9397 };
98
+
99
+static int qcom_snps_hsphy_clk_init(struct qcom_snps_hsphy *hsphy)
100
+{
101
+ struct device *dev = hsphy->dev;
102
+
103
+ hsphy->num_clks = 2;
104
+ hsphy->clks = devm_kcalloc(dev, hsphy->num_clks, sizeof(*hsphy->clks), GFP_KERNEL);
105
+ if (!hsphy->clks)
106
+ return -ENOMEM;
107
+
108
+ /*
109
+ * TODO: Currently no device tree instantiation of the PHY is using the clock.
110
+ * This needs to be fixed in order for this code to be able to use devm_clk_bulk_get().
111
+ */
112
+ hsphy->clks[0].id = "cfg_ahb";
113
+ hsphy->clks[0].clk = devm_clk_get_optional(dev, "cfg_ahb");
114
+ if (IS_ERR(hsphy->clks[0].clk))
115
+ return dev_err_probe(dev, PTR_ERR(hsphy->clks[0].clk),
116
+ "failed to get cfg_ahb clk\n");
117
+
118
+ hsphy->clks[1].id = "ref";
119
+ hsphy->clks[1].clk = devm_clk_get(dev, "ref");
120
+ if (IS_ERR(hsphy->clks[1].clk))
121
+ return dev_err_probe(dev, PTR_ERR(hsphy->clks[1].clk),
122
+ "failed to get ref clk\n");
123
+
124
+ return 0;
125
+}
94126
95127 static inline void qcom_snps_hsphy_write_mask(void __iomem *base, u32 offset,
96128 u32 mask, u32 val)
....@@ -122,21 +154,12 @@
122154 0, USB2_AUTO_RESUME);
123155 }
124156
125
- clk_disable_unprepare(hsphy->cfg_ahb_clk);
126157 return 0;
127158 }
128159
129160 static int qcom_snps_hsphy_resume(struct qcom_snps_hsphy *hsphy)
130161 {
131
- int ret;
132
-
133162 dev_dbg(&hsphy->phy->dev, "Resume QCOM SNPS PHY, mode\n");
134
-
135
- ret = clk_prepare_enable(hsphy->cfg_ahb_clk);
136
- if (ret) {
137
- dev_err(&hsphy->phy->dev, "failed to enable cfg ahb clock\n");
138
- return ret;
139
- }
140163
141164 return 0;
142165 }
....@@ -148,8 +171,7 @@
148171 if (!hsphy->phy_initialized)
149172 return 0;
150173
151
- qcom_snps_hsphy_suspend(hsphy);
152
- return 0;
174
+ return qcom_snps_hsphy_suspend(hsphy);
153175 }
154176
155177 static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev)
....@@ -159,8 +181,7 @@
159181 if (!hsphy->phy_initialized)
160182 return 0;
161183
162
- qcom_snps_hsphy_resume(hsphy);
163
- return 0;
184
+ return qcom_snps_hsphy_resume(hsphy);
164185 }
165186
166187 static int qcom_snps_hsphy_set_mode(struct phy *phy, enum phy_mode mode,
....@@ -183,16 +204,16 @@
183204 if (ret)
184205 return ret;
185206
186
- ret = clk_prepare_enable(hsphy->cfg_ahb_clk);
207
+ ret = clk_bulk_prepare_enable(hsphy->num_clks, hsphy->clks);
187208 if (ret) {
188
- dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret);
209
+ dev_err(&phy->dev, "failed to enable clocks, %d\n", ret);
189210 goto poweroff_phy;
190211 }
191212
192213 ret = reset_control_assert(hsphy->phy_reset);
193214 if (ret) {
194215 dev_err(&phy->dev, "failed to assert phy_reset, %d\n", ret);
195
- goto disable_ahb_clk;
216
+ goto disable_clks;
196217 }
197218
198219 usleep_range(100, 150);
....@@ -200,7 +221,7 @@
200221 ret = reset_control_deassert(hsphy->phy_reset);
201222 if (ret) {
202223 dev_err(&phy->dev, "failed to de-assert phy_reset, %d\n", ret);
203
- goto disable_ahb_clk;
224
+ goto disable_clks;
204225 }
205226
206227 qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_CFG0,
....@@ -246,8 +267,8 @@
246267
247268 return 0;
248269
249
-disable_ahb_clk:
250
- clk_disable_unprepare(hsphy->cfg_ahb_clk);
270
+disable_clks:
271
+ clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks);
251272 poweroff_phy:
252273 regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs);
253274
....@@ -259,7 +280,7 @@
259280 struct qcom_snps_hsphy *hsphy = phy_get_drvdata(phy);
260281
261282 reset_control_assert(hsphy->phy_reset);
262
- clk_disable_unprepare(hsphy->cfg_ahb_clk);
283
+ clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks);
263284 regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs);
264285 hsphy->phy_initialized = false;
265286
....@@ -299,17 +320,15 @@
299320 if (!hsphy)
300321 return -ENOMEM;
301322
323
+ hsphy->dev = dev;
324
+
302325 hsphy->base = devm_platform_ioremap_resource(pdev, 0);
303326 if (IS_ERR(hsphy->base))
304327 return PTR_ERR(hsphy->base);
305328
306
- hsphy->ref_clk = devm_clk_get(dev, "ref");
307
- if (IS_ERR(hsphy->ref_clk)) {
308
- ret = PTR_ERR(hsphy->ref_clk);
309
- if (ret != -EPROBE_DEFER)
310
- dev_err(dev, "failed to get ref clk, %d\n", ret);
311
- return ret;
312
- }
329
+ ret = qcom_snps_hsphy_clk_init(hsphy);
330
+ if (ret)
331
+ return dev_err_probe(dev, ret, "failed to initialize clocks\n");
313332
314333 hsphy->phy_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
315334 if (IS_ERR(hsphy->phy_reset)) {
....@@ -322,12 +341,9 @@
322341 hsphy->vregs[i].supply = qcom_snps_hsphy_vreg_names[i];
323342
324343 ret = devm_regulator_bulk_get(dev, num, hsphy->vregs);
325
- if (ret) {
326
- if (ret != -EPROBE_DEFER)
327
- dev_err(dev, "failed to get regulator supplies: %d\n",
328
- ret);
329
- return ret;
330
- }
344
+ if (ret)
345
+ return dev_err_probe(dev, ret,
346
+ "failed to get regulator supplies\n");
331347
332348 pm_runtime_set_active(dev);
333349 pm_runtime_enable(dev);