OPP: Add dev_pm_opp_add_dynamic() to allow more flexibility
authorUlf Hansson <ulf.hansson@linaro.org>
Mon, 25 Sep 2023 13:17:09 +0000 (15:17 +0200)
committerViresh Kumar <viresh.kumar@linaro.org>
Fri, 6 Oct 2023 07:07:33 +0000 (12:37 +0530)
The dev_pm_opp_add() API is limited to add dynamic OPPs with a frequency
and a voltage level. To enable more flexibility, let's add a new API,
dev_pm_opp_add_dynamic() that's takes a struct dev_pm_opp_data* instead of
a list of in-parameters.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
drivers/opp/core.c
drivers/opp/of.c
drivers/opp/opp.h
include/linux/pm_opp.h

index 919cc53..54b6138 100644 (file)
@@ -2002,8 +2002,7 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
  * _opp_add_v1() - Allocate a OPP based on v1 bindings.
  * @opp_table: OPP table
  * @dev:       device for which we do this operation
- * @freq:      Frequency in Hz for this OPP
- * @u_volt:    Voltage in uVolts for this OPP
+ * @data:      The OPP data for the OPP to add
  * @dynamic:   Dynamically added OPPs.
  *
  * This function adds an opp definition to the opp table and returns status.
@@ -2021,10 +2020,10 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
  * -ENOMEM     Memory allocation failure
  */
 int _opp_add_v1(struct opp_table *opp_table, struct device *dev,
-               unsigned long freq, long u_volt, bool dynamic)
+               struct dev_pm_opp_data *data, bool dynamic)
 {
        struct dev_pm_opp *new_opp;
-       unsigned long tol;
+       unsigned long tol, u_volt = data->u_volt;
        int ret;
 
        if (!assert_single_clk(opp_table))
@@ -2035,7 +2034,7 @@ int _opp_add_v1(struct opp_table *opp_table, struct device *dev,
                return -ENOMEM;
 
        /* populate the opp table */
-       new_opp->rates[0] = freq;
+       new_opp->rates[0] = data->freq;
        tol = u_volt * opp_table->voltage_tolerance_v1 / 100;
        new_opp->supplies[0].u_volt = u_volt;
        new_opp->supplies[0].u_volt_min = u_volt - tol;
@@ -2825,10 +2824,9 @@ unlock:
 }
 
 /**
- * dev_pm_opp_add()  - Add an OPP table from a table definitions
- * @dev:       device for which we do this operation
- * @freq:      Frequency in Hz for this OPP
- * @u_volt:    Voltage in uVolts for this OPP
+ * dev_pm_opp_add_dynamic()  - Add an OPP table from a table definitions
+ * @dev:       The device for which we do this operation
+ * @data:      The OPP data for the OPP to add
  *
  * This function adds an opp definition to the opp table and returns status.
  * The opp is made available by default and it can be controlled using
@@ -2841,7 +2839,7 @@ unlock:
  *             Duplicate OPPs (both freq and volt are same) and !opp->available
  * -ENOMEM     Memory allocation failure
  */
-int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
+int dev_pm_opp_add_dynamic(struct device *dev, struct dev_pm_opp_data *data)
 {
        struct opp_table *opp_table;
        int ret;
@@ -2853,13 +2851,13 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
        /* Fix regulator count for dynamic OPPs */
        opp_table->regulator_count = 1;
 
-       ret = _opp_add_v1(opp_table, dev, freq, u_volt, true);
+       ret = _opp_add_v1(opp_table, dev, data, true);
        if (ret)
                dev_pm_opp_put_opp_table(opp_table);
 
        return ret;
 }
-EXPORT_SYMBOL_GPL(dev_pm_opp_add);
+EXPORT_SYMBOL_GPL(dev_pm_opp_add_dynamic);
 
 /**
  * _opp_set_availability() - helper to set the availability of an opp
index ada4963..ade6d42 100644 (file)
@@ -1077,13 +1077,15 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
 
        val = prop->value;
        while (nr) {
-               unsigned long freq = be32_to_cpup(val++) * 1000;
-               unsigned long volt = be32_to_cpup(val++);
+               struct dev_pm_opp_data data = {
+                       .freq = be32_to_cpup(val++) * 1000,
+                       .u_volt = be32_to_cpup(val++),
+               };
 
-               ret = _opp_add_v1(opp_table, dev, freq, volt, false);
+               ret = _opp_add_v1(opp_table, dev, &data, false);
                if (ret) {
                        dev_err(dev, "%s: Failed to add OPP %ld (%d)\n",
-                               __func__, freq, ret);
+                               __func__, data.freq, ret);
                        goto remove_static_opp;
                }
                nr -= 2;
index 8a5ea38..fefdf98 100644 (file)
@@ -251,7 +251,7 @@ struct dev_pm_opp *_opp_allocate(struct opp_table *opp_table);
 void _opp_free(struct dev_pm_opp *opp);
 int _opp_compare_key(struct opp_table *opp_table, struct dev_pm_opp *opp1, struct dev_pm_opp *opp2);
 int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_table *opp_table);
-int _opp_add_v1(struct opp_table *opp_table, struct device *dev, unsigned long freq, long u_volt, bool dynamic);
+int _opp_add_v1(struct opp_table *opp_table, struct device *dev, struct dev_pm_opp_data *data, bool dynamic);
 void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, int last_cpu);
 struct opp_table *_add_opp_table_indexed(struct device *dev, int index, bool getclk);
 void _put_opp_list_kref(struct opp_table *opp_table);
index 91f87d7..a8ee93b 100644 (file)
@@ -92,6 +92,16 @@ struct dev_pm_opp_config {
        struct device ***virt_devs;
 };
 
+/**
+ * struct dev_pm_opp_data - The data to use to initialize an OPP.
+ * @freq: The clock rate in Hz for the OPP.
+ * @u_volt: The voltage in uV for the OPP.
+ */
+struct dev_pm_opp_data {
+       unsigned long freq;
+       unsigned long u_volt;
+};
+
 #if defined(CONFIG_PM_OPP)
 
 struct opp_table *dev_pm_opp_get_opp_table(struct device *dev);
@@ -152,8 +162,8 @@ struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev,
 
 void dev_pm_opp_put(struct dev_pm_opp *opp);
 
-int dev_pm_opp_add(struct device *dev, unsigned long freq,
-                  unsigned long u_volt);
+int dev_pm_opp_add_dynamic(struct device *dev, struct dev_pm_opp_data *opp);
+
 void dev_pm_opp_remove(struct device *dev, unsigned long freq);
 void dev_pm_opp_remove_all_dynamic(struct device *dev);
 
@@ -322,8 +332,8 @@ static inline struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev,
 
 static inline void dev_pm_opp_put(struct dev_pm_opp *opp) {}
 
-static inline int dev_pm_opp_add(struct device *dev, unsigned long freq,
-                                       unsigned long u_volt)
+static inline int
+dev_pm_opp_add_dynamic(struct device *dev, struct dev_pm_opp_data *opp)
 {
        return -EOPNOTSUPP;
 }
@@ -519,6 +529,17 @@ static inline int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_ta
 
 /* OPP Configuration helpers */
 
+static inline int dev_pm_opp_add(struct device *dev, unsigned long freq,
+                                unsigned long u_volt)
+{
+       struct dev_pm_opp_data data = {
+               .freq = freq,
+               .u_volt = u_volt,
+       };
+
+       return dev_pm_opp_add_dynamic(dev, &data);
+}
+
 /* Regulators helpers */
 static inline int dev_pm_opp_set_regulators(struct device *dev,
                                            const char * const names[])