0001
0002 #include <linux/clk.h>
0003 #include <linux/device.h>
0004 #include <linux/export.h>
0005 #include <linux/gfp.h>
0006
0007 struct devm_clk_state {
0008 struct clk *clk;
0009 void (*exit)(struct clk *clk);
0010 };
0011
0012 static void devm_clk_release(struct device *dev, void *res)
0013 {
0014 struct devm_clk_state *state = res;
0015
0016 if (state->exit)
0017 state->exit(state->clk);
0018
0019 clk_put(state->clk);
0020 }
0021
0022 static struct clk *__devm_clk_get(struct device *dev, const char *id,
0023 struct clk *(*get)(struct device *dev, const char *id),
0024 int (*init)(struct clk *clk),
0025 void (*exit)(struct clk *clk))
0026 {
0027 struct devm_clk_state *state;
0028 struct clk *clk;
0029 int ret;
0030
0031 state = devres_alloc(devm_clk_release, sizeof(*state), GFP_KERNEL);
0032 if (!state)
0033 return ERR_PTR(-ENOMEM);
0034
0035 clk = get(dev, id);
0036 if (IS_ERR(clk)) {
0037 ret = PTR_ERR(clk);
0038 goto err_clk_get;
0039 }
0040
0041 if (init) {
0042 ret = init(clk);
0043 if (ret)
0044 goto err_clk_init;
0045 }
0046
0047 state->clk = clk;
0048 state->exit = exit;
0049
0050 devres_add(dev, state);
0051
0052 return clk;
0053
0054 err_clk_init:
0055
0056 clk_put(clk);
0057 err_clk_get:
0058
0059 devres_free(state);
0060 return ERR_PTR(ret);
0061 }
0062
0063 struct clk *devm_clk_get(struct device *dev, const char *id)
0064 {
0065 return __devm_clk_get(dev, id, clk_get, NULL, NULL);
0066 }
0067 EXPORT_SYMBOL(devm_clk_get);
0068
0069 struct clk *devm_clk_get_prepared(struct device *dev, const char *id)
0070 {
0071 return __devm_clk_get(dev, id, clk_get, clk_prepare, clk_unprepare);
0072 }
0073 EXPORT_SYMBOL_GPL(devm_clk_get_prepared);
0074
0075 struct clk *devm_clk_get_enabled(struct device *dev, const char *id)
0076 {
0077 return __devm_clk_get(dev, id, clk_get,
0078 clk_prepare_enable, clk_disable_unprepare);
0079 }
0080 EXPORT_SYMBOL_GPL(devm_clk_get_enabled);
0081
0082 struct clk *devm_clk_get_optional(struct device *dev, const char *id)
0083 {
0084 return __devm_clk_get(dev, id, clk_get_optional, NULL, NULL);
0085 }
0086 EXPORT_SYMBOL(devm_clk_get_optional);
0087
0088 struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id)
0089 {
0090 return __devm_clk_get(dev, id, clk_get_optional,
0091 clk_prepare, clk_unprepare);
0092 }
0093 EXPORT_SYMBOL_GPL(devm_clk_get_optional_prepared);
0094
0095 struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id)
0096 {
0097 return __devm_clk_get(dev, id, clk_get_optional,
0098 clk_prepare_enable, clk_disable_unprepare);
0099 }
0100 EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled);
0101
0102 struct clk_bulk_devres {
0103 struct clk_bulk_data *clks;
0104 int num_clks;
0105 };
0106
0107 static void devm_clk_bulk_release(struct device *dev, void *res)
0108 {
0109 struct clk_bulk_devres *devres = res;
0110
0111 clk_bulk_put(devres->num_clks, devres->clks);
0112 }
0113
0114 static int __devm_clk_bulk_get(struct device *dev, int num_clks,
0115 struct clk_bulk_data *clks, bool optional)
0116 {
0117 struct clk_bulk_devres *devres;
0118 int ret;
0119
0120 devres = devres_alloc(devm_clk_bulk_release,
0121 sizeof(*devres), GFP_KERNEL);
0122 if (!devres)
0123 return -ENOMEM;
0124
0125 if (optional)
0126 ret = clk_bulk_get_optional(dev, num_clks, clks);
0127 else
0128 ret = clk_bulk_get(dev, num_clks, clks);
0129 if (!ret) {
0130 devres->clks = clks;
0131 devres->num_clks = num_clks;
0132 devres_add(dev, devres);
0133 } else {
0134 devres_free(devres);
0135 }
0136
0137 return ret;
0138 }
0139
0140 int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
0141 struct clk_bulk_data *clks)
0142 {
0143 return __devm_clk_bulk_get(dev, num_clks, clks, false);
0144 }
0145 EXPORT_SYMBOL_GPL(devm_clk_bulk_get);
0146
0147 int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks,
0148 struct clk_bulk_data *clks)
0149 {
0150 return __devm_clk_bulk_get(dev, num_clks, clks, true);
0151 }
0152 EXPORT_SYMBOL_GPL(devm_clk_bulk_get_optional);
0153
0154 static void devm_clk_bulk_release_all(struct device *dev, void *res)
0155 {
0156 struct clk_bulk_devres *devres = res;
0157
0158 clk_bulk_put_all(devres->num_clks, devres->clks);
0159 }
0160
0161 int __must_check devm_clk_bulk_get_all(struct device *dev,
0162 struct clk_bulk_data **clks)
0163 {
0164 struct clk_bulk_devres *devres;
0165 int ret;
0166
0167 devres = devres_alloc(devm_clk_bulk_release_all,
0168 sizeof(*devres), GFP_KERNEL);
0169 if (!devres)
0170 return -ENOMEM;
0171
0172 ret = clk_bulk_get_all(dev, &devres->clks);
0173 if (ret > 0) {
0174 *clks = devres->clks;
0175 devres->num_clks = ret;
0176 devres_add(dev, devres);
0177 } else {
0178 devres_free(devres);
0179 }
0180
0181 return ret;
0182 }
0183 EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all);
0184
0185 static int devm_clk_match(struct device *dev, void *res, void *data)
0186 {
0187 struct clk **c = res;
0188 if (!c || !*c) {
0189 WARN_ON(!c || !*c);
0190 return 0;
0191 }
0192 return *c == data;
0193 }
0194
0195 void devm_clk_put(struct device *dev, struct clk *clk)
0196 {
0197 int ret;
0198
0199 ret = devres_release(dev, devm_clk_release, devm_clk_match, clk);
0200
0201 WARN_ON(ret);
0202 }
0203 EXPORT_SYMBOL(devm_clk_put);
0204
0205 struct clk *devm_get_clk_from_child(struct device *dev,
0206 struct device_node *np, const char *con_id)
0207 {
0208 struct clk **ptr, *clk;
0209
0210 ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
0211 if (!ptr)
0212 return ERR_PTR(-ENOMEM);
0213
0214 clk = of_clk_get_by_name(np, con_id);
0215 if (!IS_ERR(clk)) {
0216 *ptr = clk;
0217 devres_add(dev, ptr);
0218 } else {
0219 devres_free(ptr);
0220 }
0221
0222 return clk;
0223 }
0224 EXPORT_SYMBOL(devm_get_clk_from_child);