1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright 2017 NXP 4 * 5 * Dong Aisheng <aisheng.dong@nxp.com> 6 */ 7 8 #include <linux/clk.h> 9 #include <linux/clk-provider.h> 10 #include <linux/device.h> 11 #include <linux/export.h> 12 #include <linux/of.h> 13 #include <linux/slab.h> 14 15 static int __must_check of_clk_bulk_get(struct device *dev, 16 struct device_node *np, int num_clks, 17 struct clk_bulk_data *clks) 18 { 19 int ret; 20 int i; 21 22 for (i = 0; i < num_clks; i++) { 23 clks[i].id = NULL; 24 clks[i].clk = NULL; 25 } 26 27 for (i = 0; i < num_clks; i++) { 28 of_property_read_string_index(np, "clock-names", i, &clks[i].id); 29 clks[i].clk = of_clk_get(np, i); 30 if (IS_ERR(clks[i].clk)) { 31 ret = PTR_ERR(clks[i].clk); 32 dev_err_probe(dev, ret, "%pOF: Failed to get clk index: %d (%s)\n", 33 np, i, clks[i].id); 34 clks[i].clk = NULL; 35 goto err; 36 } 37 } 38 39 return 0; 40 41 err: 42 clk_bulk_put(i, clks); 43 44 return ret; 45 } 46 47 static int __must_check of_clk_bulk_get_all(struct device *dev, 48 struct device_node *np, 49 struct clk_bulk_data **clks) 50 { 51 struct clk_bulk_data *clk_bulk; 52 int num_clks; 53 int ret; 54 55 num_clks = of_clk_get_parent_count(np); 56 if (!num_clks) 57 return 0; 58 59 clk_bulk = kmalloc_objs(*clk_bulk, num_clks); 60 if (!clk_bulk) 61 return -ENOMEM; 62 63 ret = of_clk_bulk_get(dev, np, num_clks, clk_bulk); 64 if (ret) { 65 kfree(clk_bulk); 66 return ret; 67 } 68 69 *clks = clk_bulk; 70 71 return num_clks; 72 } 73 74 void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) 75 { 76 while (--num_clks >= 0) { 77 clk_put(clks[num_clks].clk); 78 clks[num_clks].clk = NULL; 79 } 80 } 81 EXPORT_SYMBOL_GPL(clk_bulk_put); 82 83 static int __clk_bulk_get(struct device *dev, int num_clks, 84 struct clk_bulk_data *clks, bool optional) 85 { 86 int ret; 87 int i; 88 89 for (i = 0; i < num_clks; i++) 90 clks[i].clk = NULL; 91 92 for (i = 0; i < num_clks; i++) { 93 clks[i].clk = clk_get(dev, clks[i].id); 94 if (IS_ERR(clks[i].clk)) { 95 ret = PTR_ERR(clks[i].clk); 96 clks[i].clk = NULL; 97 98 if (ret == -ENOENT && optional) 99 continue; 100 101 dev_err_probe(dev, ret, 102 "Failed to get clk '%s'\n", 103 clks[i].id); 104 goto err; 105 } 106 } 107 108 return 0; 109 110 err: 111 clk_bulk_put(i, clks); 112 113 return ret; 114 } 115 116 int __must_check clk_bulk_get(struct device *dev, int num_clks, 117 struct clk_bulk_data *clks) 118 { 119 return __clk_bulk_get(dev, num_clks, clks, false); 120 } 121 EXPORT_SYMBOL(clk_bulk_get); 122 123 int __must_check clk_bulk_get_optional(struct device *dev, int num_clks, 124 struct clk_bulk_data *clks) 125 { 126 return __clk_bulk_get(dev, num_clks, clks, true); 127 } 128 EXPORT_SYMBOL_GPL(clk_bulk_get_optional); 129 130 void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks) 131 { 132 if (IS_ERR_OR_NULL(clks)) 133 return; 134 135 clk_bulk_put(num_clks, clks); 136 137 kfree(clks); 138 } 139 EXPORT_SYMBOL(clk_bulk_put_all); 140 141 int __must_check clk_bulk_get_all(struct device *dev, 142 struct clk_bulk_data **clks) 143 { 144 struct device_node *np = dev_of_node(dev); 145 146 if (!np) 147 return 0; 148 149 return of_clk_bulk_get_all(dev, np, clks); 150 } 151 EXPORT_SYMBOL(clk_bulk_get_all); 152 153 #ifdef CONFIG_HAVE_CLK_PREPARE 154 155 /** 156 * clk_bulk_unprepare - undo preparation of a set of clock sources 157 * @num_clks: the number of clk_bulk_data 158 * @clks: the clk_bulk_data table being unprepared 159 * 160 * clk_bulk_unprepare may sleep, which differentiates it from clk_bulk_disable. 161 * Returns 0 on success, -EERROR otherwise. 162 */ 163 void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks) 164 { 165 while (--num_clks >= 0) 166 clk_unprepare(clks[num_clks].clk); 167 } 168 EXPORT_SYMBOL_GPL(clk_bulk_unprepare); 169 170 /** 171 * clk_bulk_prepare - prepare a set of clocks 172 * @num_clks: the number of clk_bulk_data 173 * @clks: the clk_bulk_data table being prepared 174 * 175 * clk_bulk_prepare may sleep, which differentiates it from clk_bulk_enable. 176 * Returns 0 on success, -EERROR otherwise. 177 */ 178 int __must_check clk_bulk_prepare(int num_clks, 179 const struct clk_bulk_data *clks) 180 { 181 int ret; 182 int i; 183 184 for (i = 0; i < num_clks; i++) { 185 ret = clk_prepare(clks[i].clk); 186 if (ret) { 187 pr_err("Failed to prepare clk '%s': %d\n", 188 clks[i].id, ret); 189 goto err; 190 } 191 } 192 193 return 0; 194 195 err: 196 clk_bulk_unprepare(i, clks); 197 198 return ret; 199 } 200 EXPORT_SYMBOL_GPL(clk_bulk_prepare); 201 202 #endif /* CONFIG_HAVE_CLK_PREPARE */ 203 204 /** 205 * clk_bulk_disable - gate a set of clocks 206 * @num_clks: the number of clk_bulk_data 207 * @clks: the clk_bulk_data table being gated 208 * 209 * clk_bulk_disable must not sleep, which differentiates it from 210 * clk_bulk_unprepare. clk_bulk_disable must be called before 211 * clk_bulk_unprepare. 212 */ 213 void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks) 214 { 215 216 while (--num_clks >= 0) 217 clk_disable(clks[num_clks].clk); 218 } 219 EXPORT_SYMBOL_GPL(clk_bulk_disable); 220 221 /** 222 * clk_bulk_enable - ungate a set of clocks 223 * @num_clks: the number of clk_bulk_data 224 * @clks: the clk_bulk_data table being ungated 225 * 226 * clk_bulk_enable must not sleep 227 * Returns 0 on success, -EERROR otherwise. 228 */ 229 int __must_check clk_bulk_enable(int num_clks, const struct clk_bulk_data *clks) 230 { 231 int ret; 232 int i; 233 234 for (i = 0; i < num_clks; i++) { 235 ret = clk_enable(clks[i].clk); 236 if (ret) { 237 pr_err("Failed to enable clk '%s': %d\n", 238 clks[i].id, ret); 239 goto err; 240 } 241 } 242 243 return 0; 244 245 err: 246 clk_bulk_disable(i, clks); 247 248 return ret; 249 } 250 EXPORT_SYMBOL_GPL(clk_bulk_enable); 251