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