0001
0002
0003
0004
0005
0006
0007 #include <linux/clk.h>
0008 #include <linux/clk-provider.h>
0009 #include <linux/clk/clk-conf.h>
0010 #include <linux/device.h>
0011 #include <linux/of.h>
0012 #include <linux/printk.h>
0013
0014 static int __set_clk_parents(struct device_node *node, bool clk_supplier)
0015 {
0016 struct of_phandle_args clkspec;
0017 int index, rc, num_parents;
0018 struct clk *clk, *pclk;
0019
0020 num_parents = of_count_phandle_with_args(node, "assigned-clock-parents",
0021 "#clock-cells");
0022 if (num_parents == -EINVAL)
0023 pr_err("clk: invalid value of clock-parents property at %pOF\n",
0024 node);
0025
0026 for (index = 0; index < num_parents; index++) {
0027 rc = of_parse_phandle_with_args(node, "assigned-clock-parents",
0028 "#clock-cells", index, &clkspec);
0029 if (rc < 0) {
0030
0031 if (rc == -ENOENT)
0032 continue;
0033 else
0034 return rc;
0035 }
0036 if (clkspec.np == node && !clk_supplier)
0037 return 0;
0038 pclk = of_clk_get_from_provider(&clkspec);
0039 if (IS_ERR(pclk)) {
0040 if (PTR_ERR(pclk) != -EPROBE_DEFER)
0041 pr_warn("clk: couldn't get parent clock %d for %pOF\n",
0042 index, node);
0043 return PTR_ERR(pclk);
0044 }
0045
0046 rc = of_parse_phandle_with_args(node, "assigned-clocks",
0047 "#clock-cells", index, &clkspec);
0048 if (rc < 0)
0049 goto err;
0050 if (clkspec.np == node && !clk_supplier) {
0051 rc = 0;
0052 goto err;
0053 }
0054 clk = of_clk_get_from_provider(&clkspec);
0055 if (IS_ERR(clk)) {
0056 if (PTR_ERR(clk) != -EPROBE_DEFER)
0057 pr_warn("clk: couldn't get assigned clock %d for %pOF\n",
0058 index, node);
0059 rc = PTR_ERR(clk);
0060 goto err;
0061 }
0062
0063 rc = clk_set_parent(clk, pclk);
0064 if (rc < 0)
0065 pr_err("clk: failed to reparent %s to %s: %d\n",
0066 __clk_get_name(clk), __clk_get_name(pclk), rc);
0067 clk_put(clk);
0068 clk_put(pclk);
0069 }
0070 return 0;
0071 err:
0072 clk_put(pclk);
0073 return rc;
0074 }
0075
0076 static int __set_clk_rates(struct device_node *node, bool clk_supplier)
0077 {
0078 struct of_phandle_args clkspec;
0079 struct property *prop;
0080 const __be32 *cur;
0081 int rc, index = 0;
0082 struct clk *clk;
0083 u32 rate;
0084
0085 of_property_for_each_u32(node, "assigned-clock-rates", prop, cur, rate) {
0086 if (rate) {
0087 rc = of_parse_phandle_with_args(node, "assigned-clocks",
0088 "#clock-cells", index, &clkspec);
0089 if (rc < 0) {
0090
0091 if (rc == -ENOENT)
0092 continue;
0093 else
0094 return rc;
0095 }
0096 if (clkspec.np == node && !clk_supplier)
0097 return 0;
0098
0099 clk = of_clk_get_from_provider(&clkspec);
0100 if (IS_ERR(clk)) {
0101 if (PTR_ERR(clk) != -EPROBE_DEFER)
0102 pr_warn("clk: couldn't get clock %d for %pOF\n",
0103 index, node);
0104 return PTR_ERR(clk);
0105 }
0106
0107 rc = clk_set_rate(clk, rate);
0108 if (rc < 0)
0109 pr_err("clk: couldn't set %s clk rate to %u (%d), current rate: %lu\n",
0110 __clk_get_name(clk), rate, rc,
0111 clk_get_rate(clk));
0112 clk_put(clk);
0113 }
0114 index++;
0115 }
0116 return 0;
0117 }
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 int of_clk_set_defaults(struct device_node *node, bool clk_supplier)
0132 {
0133 int rc;
0134
0135 if (!node)
0136 return 0;
0137
0138 rc = __set_clk_parents(node, clk_supplier);
0139 if (rc < 0)
0140 return rc;
0141
0142 return __set_clk_rates(node, clk_supplier);
0143 }
0144 EXPORT_SYMBOL_GPL(of_clk_set_defaults);