Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright 2017 NXP
0004  *
0005  * Dong Aisheng <aisheng.dong@nxp.com>
0006  */
0007 
0008 #include <linux/clk.h>
0009 #include <linux/clk-provider.h>
0010 #include <linux/device.h>
0011 #include <linux/export.h>
0012 #include <linux/of.h>
0013 #include <linux/slab.h>
0014 
0015 static int __must_check of_clk_bulk_get(struct device_node *np, int num_clks,
0016                     struct clk_bulk_data *clks)
0017 {
0018     int ret;
0019     int i;
0020 
0021     for (i = 0; i < num_clks; i++) {
0022         clks[i].id = NULL;
0023         clks[i].clk = NULL;
0024     }
0025 
0026     for (i = 0; i < num_clks; i++) {
0027         of_property_read_string_index(np, "clock-names", i, &clks[i].id);
0028         clks[i].clk = of_clk_get(np, i);
0029         if (IS_ERR(clks[i].clk)) {
0030             ret = PTR_ERR(clks[i].clk);
0031             pr_err("%pOF: Failed to get clk index: %d ret: %d\n",
0032                    np, i, ret);
0033             clks[i].clk = NULL;
0034             goto err;
0035         }
0036     }
0037 
0038     return 0;
0039 
0040 err:
0041     clk_bulk_put(i, clks);
0042 
0043     return ret;
0044 }
0045 
0046 static int __must_check of_clk_bulk_get_all(struct device_node *np,
0047                         struct clk_bulk_data **clks)
0048 {
0049     struct clk_bulk_data *clk_bulk;
0050     int num_clks;
0051     int ret;
0052 
0053     num_clks = of_clk_get_parent_count(np);
0054     if (!num_clks)
0055         return 0;
0056 
0057     clk_bulk = kmalloc_array(num_clks, sizeof(*clk_bulk), GFP_KERNEL);
0058     if (!clk_bulk)
0059         return -ENOMEM;
0060 
0061     ret = of_clk_bulk_get(np, num_clks, clk_bulk);
0062     if (ret) {
0063         kfree(clk_bulk);
0064         return ret;
0065     }
0066 
0067     *clks = clk_bulk;
0068 
0069     return num_clks;
0070 }
0071 
0072 void clk_bulk_put(int num_clks, struct clk_bulk_data *clks)
0073 {
0074     while (--num_clks >= 0) {
0075         clk_put(clks[num_clks].clk);
0076         clks[num_clks].clk = NULL;
0077     }
0078 }
0079 EXPORT_SYMBOL_GPL(clk_bulk_put);
0080 
0081 static int __clk_bulk_get(struct device *dev, int num_clks,
0082               struct clk_bulk_data *clks, bool optional)
0083 {
0084     int ret;
0085     int i;
0086 
0087     for (i = 0; i < num_clks; i++)
0088         clks[i].clk = NULL;
0089 
0090     for (i = 0; i < num_clks; i++) {
0091         clks[i].clk = clk_get(dev, clks[i].id);
0092         if (IS_ERR(clks[i].clk)) {
0093             ret = PTR_ERR(clks[i].clk);
0094             clks[i].clk = NULL;
0095 
0096             if (ret == -ENOENT && optional)
0097                 continue;
0098 
0099             if (ret != -EPROBE_DEFER)
0100                 dev_err(dev, "Failed to get clk '%s': %d\n",
0101                     clks[i].id, ret);
0102             goto err;
0103         }
0104     }
0105 
0106     return 0;
0107 
0108 err:
0109     clk_bulk_put(i, clks);
0110 
0111     return ret;
0112 }
0113 
0114 int __must_check clk_bulk_get(struct device *dev, int num_clks,
0115                   struct clk_bulk_data *clks)
0116 {
0117     return __clk_bulk_get(dev, num_clks, clks, false);
0118 }
0119 EXPORT_SYMBOL(clk_bulk_get);
0120 
0121 int __must_check clk_bulk_get_optional(struct device *dev, int num_clks,
0122                        struct clk_bulk_data *clks)
0123 {
0124     return __clk_bulk_get(dev, num_clks, clks, true);
0125 }
0126 EXPORT_SYMBOL_GPL(clk_bulk_get_optional);
0127 
0128 void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks)
0129 {
0130     if (IS_ERR_OR_NULL(clks))
0131         return;
0132 
0133     clk_bulk_put(num_clks, clks);
0134 
0135     kfree(clks);
0136 }
0137 EXPORT_SYMBOL(clk_bulk_put_all);
0138 
0139 int __must_check clk_bulk_get_all(struct device *dev,
0140                   struct clk_bulk_data **clks)
0141 {
0142     struct device_node *np = dev_of_node(dev);
0143 
0144     if (!np)
0145         return 0;
0146 
0147     return of_clk_bulk_get_all(np, clks);
0148 }
0149 EXPORT_SYMBOL(clk_bulk_get_all);
0150 
0151 #ifdef CONFIG_HAVE_CLK_PREPARE
0152 
0153 /**
0154  * clk_bulk_unprepare - undo preparation of a set of clock sources
0155  * @num_clks: the number of clk_bulk_data
0156  * @clks: the clk_bulk_data table being unprepared
0157  *
0158  * clk_bulk_unprepare may sleep, which differentiates it from clk_bulk_disable.
0159  * Returns 0 on success, -EERROR otherwise.
0160  */
0161 void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks)
0162 {
0163     while (--num_clks >= 0)
0164         clk_unprepare(clks[num_clks].clk);
0165 }
0166 EXPORT_SYMBOL_GPL(clk_bulk_unprepare);
0167 
0168 /**
0169  * clk_bulk_prepare - prepare a set of clocks
0170  * @num_clks: the number of clk_bulk_data
0171  * @clks: the clk_bulk_data table being prepared
0172  *
0173  * clk_bulk_prepare may sleep, which differentiates it from clk_bulk_enable.
0174  * Returns 0 on success, -EERROR otherwise.
0175  */
0176 int __must_check clk_bulk_prepare(int num_clks,
0177                   const struct clk_bulk_data *clks)
0178 {
0179     int ret;
0180     int i;
0181 
0182     for (i = 0; i < num_clks; i++) {
0183         ret = clk_prepare(clks[i].clk);
0184         if (ret) {
0185             pr_err("Failed to prepare clk '%s': %d\n",
0186                 clks[i].id, ret);
0187             goto err;
0188         }
0189     }
0190 
0191     return 0;
0192 
0193 err:
0194     clk_bulk_unprepare(i, clks);
0195 
0196     return  ret;
0197 }
0198 EXPORT_SYMBOL_GPL(clk_bulk_prepare);
0199 
0200 #endif /* CONFIG_HAVE_CLK_PREPARE */
0201 
0202 /**
0203  * clk_bulk_disable - gate a set of clocks
0204  * @num_clks: the number of clk_bulk_data
0205  * @clks: the clk_bulk_data table being gated
0206  *
0207  * clk_bulk_disable must not sleep, which differentiates it from
0208  * clk_bulk_unprepare. clk_bulk_disable must be called before
0209  * clk_bulk_unprepare.
0210  */
0211 void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks)
0212 {
0213 
0214     while (--num_clks >= 0)
0215         clk_disable(clks[num_clks].clk);
0216 }
0217 EXPORT_SYMBOL_GPL(clk_bulk_disable);
0218 
0219 /**
0220  * clk_bulk_enable - ungate a set of clocks
0221  * @num_clks: the number of clk_bulk_data
0222  * @clks: the clk_bulk_data table being ungated
0223  *
0224  * clk_bulk_enable must not sleep
0225  * Returns 0 on success, -EERROR otherwise.
0226  */
0227 int __must_check clk_bulk_enable(int num_clks, const struct clk_bulk_data *clks)
0228 {
0229     int ret;
0230     int i;
0231 
0232     for (i = 0; i < num_clks; i++) {
0233         ret = clk_enable(clks[i].clk);
0234         if (ret) {
0235             pr_err("Failed to enable clk '%s': %d\n",
0236                 clks[i].id, ret);
0237             goto err;
0238         }
0239     }
0240 
0241     return 0;
0242 
0243 err:
0244     clk_bulk_disable(i, clks);
0245 
0246     return  ret;
0247 }
0248 EXPORT_SYMBOL_GPL(clk_bulk_enable);