0001
0002
0003 #include <linux/interconnect-provider.h>
0004 #include <linux/device.h>
0005 #include <linux/export.h>
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 int __must_check of_icc_bulk_get(struct device *dev, int num_paths,
0016 struct icc_bulk_data *paths)
0017 {
0018 int ret, i;
0019
0020 for (i = 0; i < num_paths; i++) {
0021 paths[i].path = of_icc_get(dev, paths[i].name);
0022 if (IS_ERR(paths[i].path)) {
0023 ret = PTR_ERR(paths[i].path);
0024 if (ret != -EPROBE_DEFER)
0025 dev_err(dev, "of_icc_get() failed on path %s (%d)\n",
0026 paths[i].name, ret);
0027 paths[i].path = NULL;
0028 goto err;
0029 }
0030 }
0031
0032 return 0;
0033
0034 err:
0035 icc_bulk_put(i, paths);
0036
0037 return ret;
0038 }
0039 EXPORT_SYMBOL_GPL(of_icc_bulk_get);
0040
0041
0042
0043
0044
0045
0046 void icc_bulk_put(int num_paths, struct icc_bulk_data *paths)
0047 {
0048 while (--num_paths >= 0) {
0049 icc_put(paths[num_paths].path);
0050 paths[num_paths].path = NULL;
0051 }
0052 }
0053 EXPORT_SYMBOL_GPL(icc_bulk_put);
0054
0055
0056
0057
0058
0059
0060
0061
0062 int icc_bulk_set_bw(int num_paths, const struct icc_bulk_data *paths)
0063 {
0064 int ret = 0;
0065 int i;
0066
0067 for (i = 0; i < num_paths; i++) {
0068 ret = icc_set_bw(paths[i].path, paths[i].avg_bw, paths[i].peak_bw);
0069 if (ret) {
0070 pr_err("icc_set_bw() failed on path %s (%d)\n", paths[i].name, ret);
0071 return ret;
0072 }
0073 }
0074
0075 return ret;
0076 }
0077 EXPORT_SYMBOL_GPL(icc_bulk_set_bw);
0078
0079
0080
0081
0082
0083
0084
0085
0086 int icc_bulk_enable(int num_paths, const struct icc_bulk_data *paths)
0087 {
0088 int ret, i;
0089
0090 for (i = 0; i < num_paths; i++) {
0091 ret = icc_enable(paths[i].path);
0092 if (ret) {
0093 pr_err("icc_enable() failed on path %s (%d)\n", paths[i].name, ret);
0094 goto err;
0095 }
0096 }
0097
0098 return 0;
0099
0100 err:
0101 icc_bulk_disable(i, paths);
0102
0103 return ret;
0104 }
0105 EXPORT_SYMBOL_GPL(icc_bulk_enable);
0106
0107
0108
0109
0110
0111
0112 void icc_bulk_disable(int num_paths, const struct icc_bulk_data *paths)
0113 {
0114 while (--num_paths >= 0)
0115 icc_disable(paths[num_paths].path);
0116 }
0117 EXPORT_SYMBOL_GPL(icc_bulk_disable);
0118
0119 struct icc_bulk_devres {
0120 struct icc_bulk_data *paths;
0121 int num_paths;
0122 };
0123
0124 static void devm_icc_bulk_release(struct device *dev, void *res)
0125 {
0126 struct icc_bulk_devres *devres = res;
0127
0128 icc_bulk_put(devres->num_paths, devres->paths);
0129 }
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139 int devm_of_icc_bulk_get(struct device *dev, int num_paths, struct icc_bulk_data *paths)
0140 {
0141 struct icc_bulk_devres *devres;
0142 int ret;
0143
0144 devres = devres_alloc(devm_icc_bulk_release, sizeof(*devres), GFP_KERNEL);
0145 if (!devres)
0146 return -ENOMEM;
0147
0148 ret = of_icc_bulk_get(dev, num_paths, paths);
0149 if (!ret) {
0150 devres->paths = paths;
0151 devres->num_paths = num_paths;
0152 devres_add(dev, devres);
0153 } else {
0154 devres_free(devres);
0155 }
0156
0157 return ret;
0158 }
0159 EXPORT_SYMBOL_GPL(devm_of_icc_bulk_get);