.. | .. |
---|
206 | 206 | } |
---|
207 | 207 | EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk); |
---|
208 | 208 | |
---|
| 209 | +/* Drop 'protected-clocks' from the list of clocks to register */ |
---|
| 210 | +static void qcom_cc_drop_protected(struct device *dev, struct qcom_cc *cc) |
---|
| 211 | +{ |
---|
| 212 | + struct device_node *np = dev->of_node; |
---|
| 213 | + struct property *prop; |
---|
| 214 | + const __be32 *p; |
---|
| 215 | + u32 i; |
---|
| 216 | + |
---|
| 217 | + of_property_for_each_u32(np, "protected-clocks", prop, p, i) { |
---|
| 218 | + if (i >= cc->num_rclks) |
---|
| 219 | + continue; |
---|
| 220 | + |
---|
| 221 | + cc->rclks[i] = NULL; |
---|
| 222 | + } |
---|
| 223 | +} |
---|
| 224 | + |
---|
209 | 225 | static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec, |
---|
210 | 226 | void *data) |
---|
211 | 227 | { |
---|
.. | .. |
---|
217 | 233 | return ERR_PTR(-EINVAL); |
---|
218 | 234 | } |
---|
219 | 235 | |
---|
220 | | - return cc->rclks[idx] ? &cc->rclks[idx]->hw : ERR_PTR(-ENOENT); |
---|
| 236 | + return cc->rclks[idx] ? &cc->rclks[idx]->hw : NULL; |
---|
221 | 237 | } |
---|
222 | 238 | |
---|
223 | 239 | int qcom_cc_really_probe(struct platform_device *pdev, |
---|
.. | .. |
---|
230 | 246 | struct gdsc_desc *scd; |
---|
231 | 247 | size_t num_clks = desc->num_clks; |
---|
232 | 248 | struct clk_regmap **rclks = desc->clks; |
---|
| 249 | + size_t num_clk_hws = desc->num_clk_hws; |
---|
| 250 | + struct clk_hw **clk_hws = desc->clk_hws; |
---|
233 | 251 | |
---|
234 | 252 | cc = devm_kzalloc(dev, sizeof(*cc), GFP_KERNEL); |
---|
235 | 253 | if (!cc) |
---|
.. | .. |
---|
266 | 284 | cc->rclks = rclks; |
---|
267 | 285 | cc->num_rclks = num_clks; |
---|
268 | 286 | |
---|
| 287 | + qcom_cc_drop_protected(dev, cc); |
---|
| 288 | + |
---|
| 289 | + for (i = 0; i < num_clk_hws; i++) { |
---|
| 290 | + ret = devm_clk_hw_register(dev, clk_hws[i]); |
---|
| 291 | + if (ret) |
---|
| 292 | + return ret; |
---|
| 293 | + } |
---|
| 294 | + |
---|
269 | 295 | for (i = 0; i < num_clks; i++) { |
---|
270 | 296 | if (!rclks[i]) |
---|
271 | 297 | continue; |
---|
.. | .. |
---|
295 | 321 | } |
---|
296 | 322 | EXPORT_SYMBOL_GPL(qcom_cc_probe); |
---|
297 | 323 | |
---|
| 324 | +int qcom_cc_probe_by_index(struct platform_device *pdev, int index, |
---|
| 325 | + const struct qcom_cc_desc *desc) |
---|
| 326 | +{ |
---|
| 327 | + struct regmap *regmap; |
---|
| 328 | + struct resource *res; |
---|
| 329 | + void __iomem *base; |
---|
| 330 | + |
---|
| 331 | + res = platform_get_resource(pdev, IORESOURCE_MEM, index); |
---|
| 332 | + base = devm_ioremap_resource(&pdev->dev, res); |
---|
| 333 | + if (IS_ERR(base)) |
---|
| 334 | + return -ENOMEM; |
---|
| 335 | + |
---|
| 336 | + regmap = devm_regmap_init_mmio(&pdev->dev, base, desc->config); |
---|
| 337 | + if (IS_ERR(regmap)) |
---|
| 338 | + return PTR_ERR(regmap); |
---|
| 339 | + |
---|
| 340 | + return qcom_cc_really_probe(pdev, desc, regmap); |
---|
| 341 | +} |
---|
| 342 | +EXPORT_SYMBOL_GPL(qcom_cc_probe_by_index); |
---|
| 343 | + |
---|
298 | 344 | MODULE_LICENSE("GPL v2"); |
---|