interconnect: add device managed bulk API
authorPeng Fan <peng.fan@nxp.com>
Sun, 3 Jul 2022 09:11:25 +0000 (17:11 +0800)
committerGeorgi Djakov <djakov@kernel.org>
Mon, 4 Jul 2022 13:14:29 +0000 (16:14 +0300)
Add device managed bulk API to simplify driver.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
Link: https://lore.kernel.org/r/20220703091132.1412063-4-peng.fan@oss.nxp.com
Signed-off-by: Georgi Djakov <djakov@kernel.org>
drivers/interconnect/bulk.c
include/linux/interconnect.h

index 448cc53..8b1d8a4 100644 (file)
@@ -115,3 +115,45 @@ void icc_bulk_disable(int num_paths, const struct icc_bulk_data *paths)
                icc_disable(paths[num_paths].path);
 }
 EXPORT_SYMBOL_GPL(icc_bulk_disable);
+
+struct icc_bulk_devres {
+       struct icc_bulk_data *paths;
+       int num_paths;
+};
+
+static void devm_icc_bulk_release(struct device *dev, void *res)
+{
+       struct icc_bulk_devres *devres = res;
+
+       icc_bulk_put(devres->num_paths, devres->paths);
+}
+
+/**
+ * devm_of_icc_bulk_get() - resource managed of_icc_bulk_get
+ * @dev: the device requesting the path
+ * @num_paths: the number of icc_bulk_data
+ * @paths: the table with the paths we want to get
+ *
+ * Returns 0 on success or negative errno otherwise.
+ */
+int devm_of_icc_bulk_get(struct device *dev, int num_paths, struct icc_bulk_data *paths)
+{
+       struct icc_bulk_devres *devres;
+       int ret;
+
+       devres = devres_alloc(devm_icc_bulk_release, sizeof(*devres), GFP_KERNEL);
+       if (!devres)
+               return -ENOMEM;
+
+       ret = of_icc_bulk_get(dev, num_paths, paths);
+       if (!ret) {
+               devres->paths = paths;
+               devres->num_paths = num_paths;
+               devres_add(dev, devres);
+       } else {
+               devres_free(devres);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(devm_of_icc_bulk_get);
index f685777..2b0e784 100644 (file)
@@ -44,6 +44,7 @@ struct icc_path *icc_get(struct device *dev, const int src_id,
                         const int dst_id);
 struct icc_path *of_icc_get(struct device *dev, const char *name);
 struct icc_path *devm_of_icc_get(struct device *dev, const char *name);
+int devm_of_icc_bulk_get(struct device *dev, int num_paths, struct icc_bulk_data *paths);
 struct icc_path *of_icc_get_by_index(struct device *dev, int idx);
 void icc_put(struct icc_path *path);
 int icc_enable(struct icc_path *path);
@@ -116,6 +117,12 @@ static inline int of_icc_bulk_get(struct device *dev, int num_paths, struct icc_
        return 0;
 }
 
+static inline int devm_of_icc_bulk_get(struct device *dev, int num_paths,
+                                      struct icc_bulk_data *paths)
+{
+       return 0;
+}
+
 static inline void icc_bulk_put(int num_paths, struct icc_bulk_data *paths)
 {
 }