OSDN Git Service

clk: Add devm_clk_bulk_get_optional() function
authorSylwester Nawrocki <s.nawrocki@samsung.com>
Wed, 19 Jun 2019 09:39:26 +0000 (11:39 +0200)
committerStephen Boyd <sboyd@kernel.org>
Tue, 25 Jun 2019 21:28:01 +0000 (14:28 -0700)
Add managed version of the clk_bulk_get_optional() helper function.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
[sboyd@kernel.org: Mark __devm_clk_bulk_get() static]
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
drivers/clk/clk-devres.c
include/linux/clk.h

index daa1fc8..be16076 100644 (file)
@@ -52,8 +52,8 @@ static void devm_clk_bulk_release(struct device *dev, void *res)
        clk_bulk_put(devres->num_clks, devres->clks);
 }
 
-int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
-                     struct clk_bulk_data *clks)
+static int __devm_clk_bulk_get(struct device *dev, int num_clks,
+                              struct clk_bulk_data *clks, bool optional)
 {
        struct clk_bulk_devres *devres;
        int ret;
@@ -63,7 +63,10 @@ int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
        if (!devres)
                return -ENOMEM;
 
-       ret = clk_bulk_get(dev, num_clks, clks);
+       if (optional)
+               ret = clk_bulk_get_optional(dev, num_clks, clks);
+       else
+               ret = clk_bulk_get(dev, num_clks, clks);
        if (!ret) {
                devres->clks = clks;
                devres->num_clks = num_clks;
@@ -74,8 +77,21 @@ int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
 
        return ret;
 }
+
+int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
+                     struct clk_bulk_data *clks)
+{
+       return __devm_clk_bulk_get(dev, num_clks, clks, false);
+}
 EXPORT_SYMBOL_GPL(devm_clk_bulk_get);
 
+int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks,
+                     struct clk_bulk_data *clks)
+{
+       return __devm_clk_bulk_get(dev, num_clks, clks, true);
+}
+EXPORT_SYMBOL_GPL(devm_clk_bulk_get_optional);
+
 int __must_check devm_clk_bulk_get_all(struct device *dev,
                                       struct clk_bulk_data **clks)
 {
index 1b50e7d..5e7b2dd 100644 (file)
@@ -360,6 +360,28 @@ int __must_check clk_bulk_get_optional(struct device *dev, int num_clks,
 int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
                                   struct clk_bulk_data *clks);
 /**
+ * devm_clk_bulk_get_optional - managed get multiple optional consumer clocks
+ * @dev: device for clock "consumer"
+ * @clks: pointer to the clk_bulk_data table of consumer
+ *
+ * Behaves the same as devm_clk_bulk_get() except where there is no clock
+ * producer.  In this case, instead of returning -ENOENT, the function returns
+ * NULL for given clk. It is assumed all clocks in clk_bulk_data are optional.
+ *
+ * Returns 0 if all clocks specified in clk_bulk_data table are obtained
+ * successfully or for any clk there was no clk provider available, otherwise
+ * returns valid IS_ERR() condition containing errno.
+ * The implementation uses @dev and @clk_bulk_data.id to determine the
+ * clock consumer, and thereby the clock producer.
+ * The clock returned is stored in each @clk_bulk_data.clk field.
+ *
+ * Drivers must assume that the clock source is not enabled.
+ *
+ * clk_bulk_get should not be called from within interrupt context.
+ */
+int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks,
+                                           struct clk_bulk_data *clks);
+/**
  * devm_clk_bulk_get_all - managed get multiple clk consumers
  * @dev: device for clock "consumer"
  * @clks: pointer to the clk_bulk_data table of consumer
@@ -760,6 +782,12 @@ static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clk
        return 0;
 }
 
+static inline int __must_check devm_clk_bulk_get_optional(struct device *dev,
+                               int num_clks, struct clk_bulk_data *clks)
+{
+       return 0;
+}
+
 static inline int __must_check devm_clk_bulk_get_all(struct device *dev,
                                                     struct clk_bulk_data **clks)
 {