1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | // |
3 | // OWL common clock driver |
4 | // |
5 | // Copyright (c) 2014 Actions Semi Inc. |
6 | // Author: David Liu <liuwei@actions-semi.com> |
7 | // |
8 | // Copyright (c) 2018 Linaro Ltd. |
9 | // Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
10 | |
11 | #include <linux/platform_device.h> |
12 | #include <linux/regmap.h> |
13 | |
14 | #include "owl-common.h" |
15 | |
16 | static const struct regmap_config owl_regmap_config = { |
17 | .reg_bits = 32, |
18 | .reg_stride = 4, |
19 | .val_bits = 32, |
20 | .max_register = 0x00cc, |
21 | .fast_io = true, |
22 | }; |
23 | |
24 | static void owl_clk_set_regmap(const struct owl_clk_desc *desc, |
25 | struct regmap *regmap) |
26 | { |
27 | int i; |
28 | struct owl_clk_common *clks; |
29 | |
30 | for (i = 0; i < desc->num_clks; i++) { |
31 | clks = desc->clks[i]; |
32 | if (!clks) |
33 | continue; |
34 | |
35 | clks->regmap = regmap; |
36 | } |
37 | } |
38 | |
39 | int owl_clk_regmap_init(struct platform_device *pdev, |
40 | struct owl_clk_desc *desc) |
41 | { |
42 | void __iomem *base; |
43 | struct regmap *regmap; |
44 | |
45 | base = devm_platform_ioremap_resource(pdev, index: 0); |
46 | if (IS_ERR(ptr: base)) |
47 | return PTR_ERR(ptr: base); |
48 | |
49 | regmap = devm_regmap_init_mmio(&pdev->dev, base, &owl_regmap_config); |
50 | if (IS_ERR(ptr: regmap)) { |
51 | pr_err("failed to init regmap\n" ); |
52 | return PTR_ERR(ptr: regmap); |
53 | } |
54 | |
55 | owl_clk_set_regmap(desc, regmap); |
56 | desc->regmap = regmap; |
57 | |
58 | return 0; |
59 | } |
60 | |
61 | int owl_clk_probe(struct device *dev, struct clk_hw_onecell_data *hw_clks) |
62 | { |
63 | int i, ret; |
64 | struct clk_hw *hw; |
65 | |
66 | for (i = 0; i < hw_clks->num; i++) { |
67 | const char *name; |
68 | |
69 | hw = hw_clks->hws[i]; |
70 | if (IS_ERR_OR_NULL(ptr: hw)) |
71 | continue; |
72 | |
73 | name = hw->init->name; |
74 | ret = devm_clk_hw_register(dev, hw); |
75 | if (ret) { |
76 | dev_err(dev, "Couldn't register clock %d - %s\n" , |
77 | i, name); |
78 | return ret; |
79 | } |
80 | } |
81 | |
82 | ret = devm_of_clk_add_hw_provider(dev, get: of_clk_hw_onecell_get, data: hw_clks); |
83 | if (ret) |
84 | dev_err(dev, "Failed to add clock provider\n" ); |
85 | |
86 | return ret; |
87 | } |
88 | |