LCOV - code coverage report
Current view: top level - drivers/opp - of.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_qemu_modules_combined.info Lines: 0 355 0.0 %
Date: 2020-09-30 20:25:01 Functions: 0 25 0.0 %
Branches: 0 232 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * Generic OPP OF helpers
       4                 :            :  *
       5                 :            :  * Copyright (C) 2009-2010 Texas Instruments Incorporated.
       6                 :            :  *      Nishanth Menon
       7                 :            :  *      Romit Dasgupta
       8                 :            :  *      Kevin Hilman
       9                 :            :  */
      10                 :            : 
      11                 :            : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      12                 :            : 
      13                 :            : #include <linux/cpu.h>
      14                 :            : #include <linux/errno.h>
      15                 :            : #include <linux/device.h>
      16                 :            : #include <linux/of_device.h>
      17                 :            : #include <linux/pm_domain.h>
      18                 :            : #include <linux/slab.h>
      19                 :            : #include <linux/export.h>
      20                 :            : #include <linux/energy_model.h>
      21                 :            : 
      22                 :            : #include "opp.h"
      23                 :            : 
      24                 :            : /*
      25                 :            :  * Returns opp descriptor node for a device node, caller must
      26                 :            :  * do of_node_put().
      27                 :            :  */
      28                 :            : static struct device_node *_opp_of_get_opp_desc_node(struct device_node *np,
      29                 :            :                                                      int index)
      30                 :            : {
      31                 :            :         /* "operating-points-v2" can be an array for power domain providers */
      32                 :          0 :         return of_parse_phandle(np, "operating-points-v2", index);
      33                 :            : }
      34                 :            : 
      35                 :            : /* Returns opp descriptor node for a device, caller must do of_node_put() */
      36                 :          0 : struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev)
      37                 :            : {
      38                 :          0 :         return _opp_of_get_opp_desc_node(dev->of_node, 0);
      39                 :            : }
      40                 :            : EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_opp_desc_node);
      41                 :            : 
      42                 :          0 : struct opp_table *_managed_opp(struct device *dev, int index)
      43                 :            : {
      44                 :            :         struct opp_table *opp_table, *managed_table = NULL;
      45                 :            :         struct device_node *np;
      46                 :            : 
      47                 :          0 :         np = _opp_of_get_opp_desc_node(dev->of_node, index);
      48         [ #  # ]:          0 :         if (!np)
      49                 :            :                 return NULL;
      50                 :            : 
      51         [ #  # ]:          0 :         list_for_each_entry(opp_table, &opp_tables, node) {
      52         [ #  # ]:          0 :                 if (opp_table->np == np) {
      53                 :            :                         /*
      54                 :            :                          * Multiple devices can point to the same OPP table and
      55                 :            :                          * so will have same node-pointer, np.
      56                 :            :                          *
      57                 :            :                          * But the OPPs will be considered as shared only if the
      58                 :            :                          * OPP table contains a "opp-shared" property.
      59                 :            :                          */
      60         [ #  # ]:          0 :                         if (opp_table->shared_opp == OPP_TABLE_ACCESS_SHARED) {
      61                 :          0 :                                 _get_opp_table_kref(opp_table);
      62                 :          0 :                                 managed_table = opp_table;
      63                 :            :                         }
      64                 :            : 
      65                 :            :                         break;
      66                 :            :                 }
      67                 :            :         }
      68                 :            : 
      69                 :          0 :         of_node_put(np);
      70                 :            : 
      71                 :          0 :         return managed_table;
      72                 :            : }
      73                 :            : 
      74                 :            : /* The caller must call dev_pm_opp_put() after the OPP is used */
      75                 :          0 : static struct dev_pm_opp *_find_opp_of_np(struct opp_table *opp_table,
      76                 :            :                                           struct device_node *opp_np)
      77                 :            : {
      78                 :            :         struct dev_pm_opp *opp;
      79                 :            : 
      80                 :          0 :         mutex_lock(&opp_table->lock);
      81                 :            : 
      82         [ #  # ]:          0 :         list_for_each_entry(opp, &opp_table->opp_list, node) {
      83         [ #  # ]:          0 :                 if (opp->np == opp_np) {
      84                 :          0 :                         dev_pm_opp_get(opp);
      85                 :          0 :                         mutex_unlock(&opp_table->lock);
      86                 :          0 :                         return opp;
      87                 :            :                 }
      88                 :            :         }
      89                 :            : 
      90                 :          0 :         mutex_unlock(&opp_table->lock);
      91                 :            : 
      92                 :          0 :         return NULL;
      93                 :            : }
      94                 :            : 
      95                 :          0 : static struct device_node *of_parse_required_opp(struct device_node *np,
      96                 :            :                                                  int index)
      97                 :            : {
      98                 :            :         struct device_node *required_np;
      99                 :            : 
     100                 :          0 :         required_np = of_parse_phandle(np, "required-opps", index);
     101         [ #  # ]:          0 :         if (unlikely(!required_np)) {
     102                 :          0 :                 pr_err("%s: Unable to parse required-opps: %pOF, index: %d\n",
     103                 :            :                        __func__, np, index);
     104                 :            :         }
     105                 :            : 
     106                 :          0 :         return required_np;
     107                 :            : }
     108                 :            : 
     109                 :            : /* The caller must call dev_pm_opp_put_opp_table() after the table is used */
     110                 :          0 : static struct opp_table *_find_table_of_opp_np(struct device_node *opp_np)
     111                 :            : {
     112                 :            :         struct opp_table *opp_table;
     113                 :            :         struct device_node *opp_table_np;
     114                 :            : 
     115                 :            :         lockdep_assert_held(&opp_table_lock);
     116                 :            : 
     117                 :          0 :         opp_table_np = of_get_parent(opp_np);
     118         [ #  # ]:          0 :         if (!opp_table_np)
     119                 :            :                 goto err;
     120                 :            : 
     121                 :            :         /* It is safe to put the node now as all we need now is its address */
     122                 :          0 :         of_node_put(opp_table_np);
     123                 :            : 
     124         [ #  # ]:          0 :         list_for_each_entry(opp_table, &opp_tables, node) {
     125         [ #  # ]:          0 :                 if (opp_table_np == opp_table->np) {
     126                 :          0 :                         _get_opp_table_kref(opp_table);
     127                 :          0 :                         return opp_table;
     128                 :            :                 }
     129                 :            :         }
     130                 :            : 
     131                 :            : err:
     132                 :            :         return ERR_PTR(-ENODEV);
     133                 :            : }
     134                 :            : 
     135                 :            : /* Free resources previously acquired by _opp_table_alloc_required_tables() */
     136                 :          0 : static void _opp_table_free_required_tables(struct opp_table *opp_table)
     137                 :            : {
     138                 :          0 :         struct opp_table **required_opp_tables = opp_table->required_opp_tables;
     139                 :            :         int i;
     140                 :            : 
     141         [ #  # ]:          0 :         if (!required_opp_tables)
     142                 :          0 :                 return;
     143                 :            : 
     144         [ #  # ]:          0 :         for (i = 0; i < opp_table->required_opp_count; i++) {
     145         [ #  # ]:          0 :                 if (IS_ERR_OR_NULL(required_opp_tables[i]))
     146                 :            :                         break;
     147                 :            : 
     148                 :          0 :                 dev_pm_opp_put_opp_table(required_opp_tables[i]);
     149                 :            :         }
     150                 :            : 
     151                 :          0 :         kfree(required_opp_tables);
     152                 :            : 
     153                 :          0 :         opp_table->required_opp_count = 0;
     154                 :          0 :         opp_table->required_opp_tables = NULL;
     155                 :            : }
     156                 :            : 
     157                 :            : /*
     158                 :            :  * Populate all devices and opp tables which are part of "required-opps" list.
     159                 :            :  * Checking only the first OPP node should be enough.
     160                 :            :  */
     161                 :          0 : static void _opp_table_alloc_required_tables(struct opp_table *opp_table,
     162                 :            :                                              struct device *dev,
     163                 :            :                                              struct device_node *opp_np)
     164                 :            : {
     165                 :            :         struct opp_table **required_opp_tables;
     166                 :            :         struct device_node *required_np, *np;
     167                 :            :         int count, i;
     168                 :            : 
     169                 :            :         /* Traversing the first OPP node is all we need */
     170                 :          0 :         np = of_get_next_available_child(opp_np, NULL);
     171         [ #  # ]:          0 :         if (!np) {
     172                 :          0 :                 dev_err(dev, "Empty OPP table\n");
     173                 :          0 :                 return;
     174                 :            :         }
     175                 :            : 
     176                 :          0 :         count = of_count_phandle_with_args(np, "required-opps", NULL);
     177         [ #  # ]:          0 :         if (!count)
     178                 :            :                 goto put_np;
     179                 :            : 
     180                 :          0 :         required_opp_tables = kcalloc(count, sizeof(*required_opp_tables),
     181                 :            :                                       GFP_KERNEL);
     182         [ #  # ]:          0 :         if (!required_opp_tables)
     183                 :            :                 goto put_np;
     184                 :            : 
     185                 :          0 :         opp_table->required_opp_tables = required_opp_tables;
     186                 :          0 :         opp_table->required_opp_count = count;
     187                 :            : 
     188         [ #  # ]:          0 :         for (i = 0; i < count; i++) {
     189                 :          0 :                 required_np = of_parse_required_opp(np, i);
     190         [ #  # ]:          0 :                 if (!required_np)
     191                 :            :                         goto free_required_tables;
     192                 :            : 
     193                 :          0 :                 required_opp_tables[i] = _find_table_of_opp_np(required_np);
     194                 :          0 :                 of_node_put(required_np);
     195                 :            : 
     196         [ #  # ]:          0 :                 if (IS_ERR(required_opp_tables[i]))
     197                 :            :                         goto free_required_tables;
     198                 :            : 
     199                 :            :                 /*
     200                 :            :                  * We only support genpd's OPPs in the "required-opps" for now,
     201                 :            :                  * as we don't know how much about other cases. Error out if the
     202                 :            :                  * required OPP doesn't belong to a genpd.
     203                 :            :                  */
     204         [ #  # ]:          0 :                 if (!required_opp_tables[i]->is_genpd) {
     205                 :          0 :                         dev_err(dev, "required-opp doesn't belong to genpd: %pOF\n",
     206                 :            :                                 required_np);
     207                 :          0 :                         goto free_required_tables;
     208                 :            :                 }
     209                 :            :         }
     210                 :            : 
     211                 :            :         goto put_np;
     212                 :            : 
     213                 :            : free_required_tables:
     214                 :          0 :         _opp_table_free_required_tables(opp_table);
     215                 :            : put_np:
     216                 :          0 :         of_node_put(np);
     217                 :            : }
     218                 :            : 
     219                 :          0 : void _of_init_opp_table(struct opp_table *opp_table, struct device *dev,
     220                 :            :                         int index)
     221                 :            : {
     222                 :            :         struct device_node *np, *opp_np;
     223                 :            :         u32 val;
     224                 :            : 
     225                 :            :         /*
     226                 :            :          * Only required for backward compatibility with v1 bindings, but isn't
     227                 :            :          * harmful for other cases. And so we do it unconditionally.
     228                 :            :          */
     229                 :          0 :         np = of_node_get(dev->of_node);
     230         [ #  # ]:          0 :         if (!np)
     231                 :          0 :                 return;
     232                 :            : 
     233         [ #  # ]:          0 :         if (!of_property_read_u32(np, "clock-latency", &val))
     234                 :          0 :                 opp_table->clock_latency_ns_max = val;
     235                 :            :         of_property_read_u32(np, "voltage-tolerance",
     236                 :          0 :                              &opp_table->voltage_tolerance_v1);
     237                 :            : 
     238         [ #  # ]:          0 :         if (of_find_property(np, "#power-domain-cells", NULL))
     239                 :          0 :                 opp_table->is_genpd = true;
     240                 :            : 
     241                 :            :         /* Get OPP table node */
     242                 :            :         opp_np = _opp_of_get_opp_desc_node(np, index);
     243                 :          0 :         of_node_put(np);
     244                 :            : 
     245         [ #  # ]:          0 :         if (!opp_np)
     246                 :            :                 return;
     247                 :            : 
     248         [ #  # ]:          0 :         if (of_property_read_bool(opp_np, "opp-shared"))
     249                 :          0 :                 opp_table->shared_opp = OPP_TABLE_ACCESS_SHARED;
     250                 :            :         else
     251                 :          0 :                 opp_table->shared_opp = OPP_TABLE_ACCESS_EXCLUSIVE;
     252                 :            : 
     253                 :          0 :         opp_table->np = opp_np;
     254                 :            : 
     255                 :          0 :         _opp_table_alloc_required_tables(opp_table, dev, opp_np);
     256                 :          0 :         of_node_put(opp_np);
     257                 :            : }
     258                 :            : 
     259                 :          0 : void _of_clear_opp_table(struct opp_table *opp_table)
     260                 :            : {
     261                 :          0 :         _opp_table_free_required_tables(opp_table);
     262                 :          0 : }
     263                 :            : 
     264                 :            : /*
     265                 :            :  * Release all resources previously acquired with a call to
     266                 :            :  * _of_opp_alloc_required_opps().
     267                 :            :  */
     268                 :          0 : void _of_opp_free_required_opps(struct opp_table *opp_table,
     269                 :            :                                 struct dev_pm_opp *opp)
     270                 :            : {
     271                 :          0 :         struct dev_pm_opp **required_opps = opp->required_opps;
     272                 :            :         int i;
     273                 :            : 
     274         [ #  # ]:          0 :         if (!required_opps)
     275                 :          0 :                 return;
     276                 :            : 
     277         [ #  # ]:          0 :         for (i = 0; i < opp_table->required_opp_count; i++) {
     278         [ #  # ]:          0 :                 if (!required_opps[i])
     279                 :            :                         break;
     280                 :            : 
     281                 :            :                 /* Put the reference back */
     282                 :          0 :                 dev_pm_opp_put(required_opps[i]);
     283                 :            :         }
     284                 :            : 
     285                 :          0 :         kfree(required_opps);
     286                 :          0 :         opp->required_opps = NULL;
     287                 :            : }
     288                 :            : 
     289                 :            : /* Populate all required OPPs which are part of "required-opps" list */
     290                 :          0 : static int _of_opp_alloc_required_opps(struct opp_table *opp_table,
     291                 :            :                                        struct dev_pm_opp *opp)
     292                 :            : {
     293                 :            :         struct dev_pm_opp **required_opps;
     294                 :            :         struct opp_table *required_table;
     295                 :            :         struct device_node *np;
     296                 :          0 :         int i, ret, count = opp_table->required_opp_count;
     297                 :            : 
     298         [ #  # ]:          0 :         if (!count)
     299                 :            :                 return 0;
     300                 :            : 
     301                 :            :         required_opps = kcalloc(count, sizeof(*required_opps), GFP_KERNEL);
     302         [ #  # ]:          0 :         if (!required_opps)
     303                 :            :                 return -ENOMEM;
     304                 :            : 
     305                 :          0 :         opp->required_opps = required_opps;
     306                 :            : 
     307         [ #  # ]:          0 :         for (i = 0; i < count; i++) {
     308                 :          0 :                 required_table = opp_table->required_opp_tables[i];
     309                 :            : 
     310                 :          0 :                 np = of_parse_required_opp(opp->np, i);
     311         [ #  # ]:          0 :                 if (unlikely(!np)) {
     312                 :            :                         ret = -ENODEV;
     313                 :            :                         goto free_required_opps;
     314                 :            :                 }
     315                 :            : 
     316                 :          0 :                 required_opps[i] = _find_opp_of_np(required_table, np);
     317                 :          0 :                 of_node_put(np);
     318                 :            : 
     319         [ #  # ]:          0 :                 if (!required_opps[i]) {
     320                 :          0 :                         pr_err("%s: Unable to find required OPP node: %pOF (%d)\n",
     321                 :            :                                __func__, opp->np, i);
     322                 :            :                         ret = -ENODEV;
     323                 :          0 :                         goto free_required_opps;
     324                 :            :                 }
     325                 :            :         }
     326                 :            : 
     327                 :            :         return 0;
     328                 :            : 
     329                 :            : free_required_opps:
     330                 :          0 :         _of_opp_free_required_opps(opp_table, opp);
     331                 :            : 
     332                 :          0 :         return ret;
     333                 :            : }
     334                 :            : 
     335                 :          0 : static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table,
     336                 :            :                               struct device_node *np)
     337                 :            : {
     338                 :          0 :         unsigned int count = opp_table->supported_hw_count;
     339                 :            :         u32 version;
     340                 :            :         int ret;
     341                 :            : 
     342         [ #  # ]:          0 :         if (!opp_table->supported_hw) {
     343                 :            :                 /*
     344                 :            :                  * In the case that no supported_hw has been set by the
     345                 :            :                  * platform but there is an opp-supported-hw value set for
     346                 :            :                  * an OPP then the OPP should not be enabled as there is
     347                 :            :                  * no way to see if the hardware supports it.
     348                 :            :                  */
     349         [ #  # ]:          0 :                 if (of_find_property(np, "opp-supported-hw", NULL))
     350                 :            :                         return false;
     351                 :            :                 else
     352                 :          0 :                         return true;
     353                 :            :         }
     354                 :            : 
     355         [ #  # ]:          0 :         while (count--) {
     356                 :          0 :                 ret = of_property_read_u32_index(np, "opp-supported-hw", count,
     357                 :            :                                                  &version);
     358         [ #  # ]:          0 :                 if (ret) {
     359                 :          0 :                         dev_warn(dev, "%s: failed to read opp-supported-hw property at index %d: %d\n",
     360                 :            :                                  __func__, count, ret);
     361                 :          0 :                         return false;
     362                 :            :                 }
     363                 :            : 
     364                 :            :                 /* Both of these are bitwise masks of the versions */
     365         [ #  # ]:          0 :                 if (!(version & opp_table->supported_hw[count]))
     366                 :            :                         return false;
     367                 :            :         }
     368                 :            : 
     369                 :            :         return true;
     370                 :            : }
     371                 :            : 
     372                 :          0 : static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
     373                 :            :                               struct opp_table *opp_table)
     374                 :            : {
     375                 :            :         u32 *microvolt, *microamp = NULL;
     376                 :          0 :         int supplies = opp_table->regulator_count, vcount, icount, ret, i, j;
     377                 :            :         struct property *prop = NULL;
     378                 :            :         char name[NAME_MAX];
     379                 :            : 
     380                 :            :         /* Search for "opp-microvolt-<name>" */
     381         [ #  # ]:          0 :         if (opp_table->prop_name) {
     382                 :          0 :                 snprintf(name, sizeof(name), "opp-microvolt-%s",
     383                 :            :                          opp_table->prop_name);
     384                 :          0 :                 prop = of_find_property(opp->np, name, NULL);
     385                 :            :         }
     386                 :            : 
     387         [ #  # ]:          0 :         if (!prop) {
     388                 :            :                 /* Search for "opp-microvolt" */
     389                 :          0 :                 sprintf(name, "opp-microvolt");
     390                 :          0 :                 prop = of_find_property(opp->np, name, NULL);
     391                 :            : 
     392                 :            :                 /* Missing property isn't a problem, but an invalid entry is */
     393         [ #  # ]:          0 :                 if (!prop) {
     394         [ #  # ]:          0 :                         if (unlikely(supplies == -1)) {
     395                 :            :                                 /* Initialize regulator_count */
     396                 :          0 :                                 opp_table->regulator_count = 0;
     397                 :          0 :                                 return 0;
     398                 :            :                         }
     399                 :            : 
     400         [ #  # ]:          0 :                         if (!supplies)
     401                 :            :                                 return 0;
     402                 :            : 
     403                 :          0 :                         dev_err(dev, "%s: opp-microvolt missing although OPP managing regulators\n",
     404                 :            :                                 __func__);
     405                 :          0 :                         return -EINVAL;
     406                 :            :                 }
     407                 :            :         }
     408                 :            : 
     409         [ #  # ]:          0 :         if (unlikely(supplies == -1)) {
     410                 :            :                 /* Initialize regulator_count */
     411                 :          0 :                 supplies = opp_table->regulator_count = 1;
     412         [ #  # ]:          0 :         } else if (unlikely(!supplies)) {
     413                 :          0 :                 dev_err(dev, "%s: opp-microvolt wasn't expected\n", __func__);
     414                 :          0 :                 return -EINVAL;
     415                 :            :         }
     416                 :            : 
     417                 :          0 :         vcount = of_property_count_u32_elems(opp->np, name);
     418         [ #  # ]:          0 :         if (vcount < 0) {
     419                 :          0 :                 dev_err(dev, "%s: Invalid %s property (%d)\n",
     420                 :            :                         __func__, name, vcount);
     421                 :          0 :                 return vcount;
     422                 :            :         }
     423                 :            : 
     424                 :            :         /* There can be one or three elements per supply */
     425   [ #  #  #  # ]:          0 :         if (vcount != supplies && vcount != supplies * 3) {
     426                 :          0 :                 dev_err(dev, "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n",
     427                 :            :                         __func__, name, vcount, supplies);
     428                 :          0 :                 return -EINVAL;
     429                 :            :         }
     430                 :            : 
     431                 :          0 :         microvolt = kmalloc_array(vcount, sizeof(*microvolt), GFP_KERNEL);
     432         [ #  # ]:          0 :         if (!microvolt)
     433                 :            :                 return -ENOMEM;
     434                 :            : 
     435                 :          0 :         ret = of_property_read_u32_array(opp->np, name, microvolt, vcount);
     436         [ #  # ]:          0 :         if (ret) {
     437                 :          0 :                 dev_err(dev, "%s: error parsing %s: %d\n", __func__, name, ret);
     438                 :            :                 ret = -EINVAL;
     439                 :          0 :                 goto free_microvolt;
     440                 :            :         }
     441                 :            : 
     442                 :            :         /* Search for "opp-microamp-<name>" */
     443                 :            :         prop = NULL;
     444         [ #  # ]:          0 :         if (opp_table->prop_name) {
     445                 :          0 :                 snprintf(name, sizeof(name), "opp-microamp-%s",
     446                 :            :                          opp_table->prop_name);
     447                 :          0 :                 prop = of_find_property(opp->np, name, NULL);
     448                 :            :         }
     449                 :            : 
     450         [ #  # ]:          0 :         if (!prop) {
     451                 :            :                 /* Search for "opp-microamp" */
     452                 :          0 :                 sprintf(name, "opp-microamp");
     453                 :          0 :                 prop = of_find_property(opp->np, name, NULL);
     454                 :            :         }
     455                 :            : 
     456         [ #  # ]:          0 :         if (prop) {
     457                 :          0 :                 icount = of_property_count_u32_elems(opp->np, name);
     458         [ #  # ]:          0 :                 if (icount < 0) {
     459                 :          0 :                         dev_err(dev, "%s: Invalid %s property (%d)\n", __func__,
     460                 :            :                                 name, icount);
     461                 :            :                         ret = icount;
     462                 :          0 :                         goto free_microvolt;
     463                 :            :                 }
     464                 :            : 
     465         [ #  # ]:          0 :                 if (icount != supplies) {
     466                 :          0 :                         dev_err(dev, "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n",
     467                 :            :                                 __func__, name, icount, supplies);
     468                 :            :                         ret = -EINVAL;
     469                 :          0 :                         goto free_microvolt;
     470                 :            :                 }
     471                 :            : 
     472                 :          0 :                 microamp = kmalloc_array(icount, sizeof(*microamp), GFP_KERNEL);
     473         [ #  # ]:          0 :                 if (!microamp) {
     474                 :            :                         ret = -EINVAL;
     475                 :            :                         goto free_microvolt;
     476                 :            :                 }
     477                 :            : 
     478                 :          0 :                 ret = of_property_read_u32_array(opp->np, name, microamp,
     479                 :            :                                                  icount);
     480         [ #  # ]:          0 :                 if (ret) {
     481                 :          0 :                         dev_err(dev, "%s: error parsing %s: %d\n", __func__,
     482                 :            :                                 name, ret);
     483                 :            :                         ret = -EINVAL;
     484                 :          0 :                         goto free_microamp;
     485                 :            :                 }
     486                 :            :         }
     487                 :            : 
     488         [ #  # ]:          0 :         for (i = 0, j = 0; i < supplies; i++) {
     489                 :          0 :                 opp->supplies[i].u_volt = microvolt[j++];
     490                 :            : 
     491         [ #  # ]:          0 :                 if (vcount == supplies) {
     492                 :          0 :                         opp->supplies[i].u_volt_min = opp->supplies[i].u_volt;
     493                 :          0 :                         opp->supplies[i].u_volt_max = opp->supplies[i].u_volt;
     494                 :            :                 } else {
     495                 :          0 :                         opp->supplies[i].u_volt_min = microvolt[j++];
     496                 :          0 :                         opp->supplies[i].u_volt_max = microvolt[j++];
     497                 :            :                 }
     498                 :            : 
     499         [ #  # ]:          0 :                 if (microamp)
     500                 :          0 :                         opp->supplies[i].u_amp = microamp[i];
     501                 :            :         }
     502                 :            : 
     503                 :            : free_microamp:
     504                 :          0 :         kfree(microamp);
     505                 :            : free_microvolt:
     506                 :          0 :         kfree(microvolt);
     507                 :            : 
     508                 :          0 :         return ret;
     509                 :            : }
     510                 :            : 
     511                 :            : /**
     512                 :            :  * dev_pm_opp_of_remove_table() - Free OPP table entries created from static DT
     513                 :            :  *                                entries
     514                 :            :  * @dev:        device pointer used to lookup OPP table.
     515                 :            :  *
     516                 :            :  * Free OPPs created using static entries present in DT.
     517                 :            :  */
     518                 :          0 : void dev_pm_opp_of_remove_table(struct device *dev)
     519                 :            : {
     520                 :          0 :         _dev_pm_opp_find_and_remove_table(dev);
     521                 :          0 : }
     522                 :            : EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table);
     523                 :            : 
     524                 :            : /**
     525                 :            :  * _opp_add_static_v2() - Allocate static OPPs (As per 'v2' DT bindings)
     526                 :            :  * @opp_table:  OPP table
     527                 :            :  * @dev:        device for which we do this operation
     528                 :            :  * @np:         device node
     529                 :            :  *
     530                 :            :  * This function adds an opp definition to the opp table and returns status. The
     531                 :            :  * opp can be controlled using dev_pm_opp_enable/disable functions and may be
     532                 :            :  * removed by dev_pm_opp_remove.
     533                 :            :  *
     534                 :            :  * Return:
     535                 :            :  * Valid OPP pointer:
     536                 :            :  *              On success
     537                 :            :  * NULL:
     538                 :            :  *              Duplicate OPPs (both freq and volt are same) and opp->available
     539                 :            :  *              OR if the OPP is not supported by hardware.
     540                 :            :  * ERR_PTR(-EEXIST):
     541                 :            :  *              Freq are same and volt are different OR
     542                 :            :  *              Duplicate OPPs (both freq and volt are same) and !opp->available
     543                 :            :  * ERR_PTR(-ENOMEM):
     544                 :            :  *              Memory allocation failure
     545                 :            :  * ERR_PTR(-EINVAL):
     546                 :            :  *              Failed parsing the OPP node
     547                 :            :  */
     548                 :          0 : static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table,
     549                 :            :                 struct device *dev, struct device_node *np)
     550                 :            : {
     551                 :            :         struct dev_pm_opp *new_opp;
     552                 :          0 :         u64 rate = 0;
     553                 :            :         u32 val;
     554                 :            :         int ret;
     555                 :            :         bool rate_not_available = false;
     556                 :            : 
     557                 :          0 :         new_opp = _opp_allocate(opp_table);
     558         [ #  # ]:          0 :         if (!new_opp)
     559                 :            :                 return ERR_PTR(-ENOMEM);
     560                 :            : 
     561                 :          0 :         ret = of_property_read_u64(np, "opp-hz", &rate);
     562         [ #  # ]:          0 :         if (ret < 0) {
     563                 :            :                 /* "opp-hz" is optional for devices like power domains. */
     564         [ #  # ]:          0 :                 if (!opp_table->is_genpd) {
     565                 :          0 :                         dev_err(dev, "%s: opp-hz not found\n", __func__);
     566                 :          0 :                         goto free_opp;
     567                 :            :                 }
     568                 :            : 
     569                 :            :                 rate_not_available = true;
     570                 :            :         } else {
     571                 :            :                 /*
     572                 :            :                  * Rate is defined as an unsigned long in clk API, and so
     573                 :            :                  * casting explicitly to its type. Must be fixed once rate is 64
     574                 :            :                  * bit guaranteed in clk API.
     575                 :            :                  */
     576                 :          0 :                 new_opp->rate = (unsigned long)rate;
     577                 :            :         }
     578                 :            : 
     579                 :          0 :         of_property_read_u32(np, "opp-level", &new_opp->level);
     580                 :            : 
     581                 :            :         /* Check if the OPP supports hardware's hierarchy of versions or not */
     582         [ #  # ]:          0 :         if (!_opp_is_supported(dev, opp_table, np)) {
     583                 :            :                 dev_dbg(dev, "OPP not supported by hardware: %llu\n", rate);
     584                 :            :                 goto free_opp;
     585                 :            :         }
     586                 :            : 
     587                 :          0 :         new_opp->turbo = of_property_read_bool(np, "turbo-mode");
     588                 :            : 
     589                 :          0 :         new_opp->np = np;
     590                 :          0 :         new_opp->dynamic = false;
     591                 :          0 :         new_opp->available = true;
     592                 :            : 
     593                 :          0 :         ret = _of_opp_alloc_required_opps(opp_table, new_opp);
     594         [ #  # ]:          0 :         if (ret)
     595                 :            :                 goto free_opp;
     596                 :            : 
     597         [ #  # ]:          0 :         if (!of_property_read_u32(np, "clock-latency-ns", &val))
     598                 :          0 :                 new_opp->clock_latency_ns = val;
     599                 :            : 
     600                 :          0 :         ret = opp_parse_supplies(new_opp, dev, opp_table);
     601         [ #  # ]:          0 :         if (ret)
     602                 :            :                 goto free_required_opps;
     603                 :            : 
     604         [ #  # ]:          0 :         if (opp_table->is_genpd)
     605                 :          0 :                 new_opp->pstate = pm_genpd_opp_to_performance_state(dev, new_opp);
     606                 :            : 
     607                 :          0 :         ret = _opp_add(dev, new_opp, opp_table, rate_not_available);
     608         [ #  # ]:          0 :         if (ret) {
     609                 :            :                 /* Don't return error for duplicate OPPs */
     610         [ #  # ]:          0 :                 if (ret == -EBUSY)
     611                 :            :                         ret = 0;
     612                 :            :                 goto free_required_opps;
     613                 :            :         }
     614                 :            : 
     615                 :            :         /* OPP to select on device suspend */
     616         [ #  # ]:          0 :         if (of_property_read_bool(np, "opp-suspend")) {
     617         [ #  # ]:          0 :                 if (opp_table->suspend_opp) {
     618                 :            :                         /* Pick the OPP with higher rate as suspend OPP */
     619         [ #  # ]:          0 :                         if (new_opp->rate > opp_table->suspend_opp->rate) {
     620                 :          0 :                                 opp_table->suspend_opp->suspend = false;
     621                 :          0 :                                 new_opp->suspend = true;
     622                 :          0 :                                 opp_table->suspend_opp = new_opp;
     623                 :            :                         }
     624                 :            :                 } else {
     625                 :          0 :                         new_opp->suspend = true;
     626                 :          0 :                         opp_table->suspend_opp = new_opp;
     627                 :            :                 }
     628                 :            :         }
     629                 :            : 
     630         [ #  # ]:          0 :         if (new_opp->clock_latency_ns > opp_table->clock_latency_ns_max)
     631                 :          0 :                 opp_table->clock_latency_ns_max = new_opp->clock_latency_ns;
     632                 :            : 
     633                 :            :         pr_debug("%s: turbo:%d rate:%lu uv:%lu uvmin:%lu uvmax:%lu latency:%lu\n",
     634                 :            :                  __func__, new_opp->turbo, new_opp->rate,
     635                 :            :                  new_opp->supplies[0].u_volt, new_opp->supplies[0].u_volt_min,
     636                 :            :                  new_opp->supplies[0].u_volt_max, new_opp->clock_latency_ns);
     637                 :            : 
     638                 :            :         /*
     639                 :            :          * Notify the changes in the availability of the operable
     640                 :            :          * frequency/voltage list.
     641                 :            :          */
     642                 :          0 :         blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ADD, new_opp);
     643                 :          0 :         return new_opp;
     644                 :            : 
     645                 :            : free_required_opps:
     646                 :          0 :         _of_opp_free_required_opps(opp_table, new_opp);
     647                 :            : free_opp:
     648                 :          0 :         _opp_free(new_opp);
     649                 :            : 
     650                 :          0 :         return ERR_PTR(ret);
     651                 :            : }
     652                 :            : 
     653                 :            : /* Initializes OPP tables based on new bindings */
     654                 :          0 : static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table)
     655                 :            : {
     656                 :            :         struct device_node *np;
     657                 :            :         int ret, count = 0, pstate_count = 0;
     658                 :            :         struct dev_pm_opp *opp;
     659                 :            : 
     660                 :            :         /* OPP table is already initialized for the device */
     661         [ #  # ]:          0 :         if (opp_table->parsed_static_opps) {
     662                 :            :                 kref_get(&opp_table->list_kref);
     663                 :          0 :                 return 0;
     664                 :            :         }
     665                 :            : 
     666                 :            :         /*
     667                 :            :          * Re-initialize list_kref every time we add static OPPs to the OPP
     668                 :            :          * table as the reference count may be 0 after the last tie static OPPs
     669                 :            :          * were removed.
     670                 :            :          */
     671                 :            :         kref_init(&opp_table->list_kref);
     672                 :            : 
     673                 :            :         /* We have opp-table node now, iterate over it and add OPPs */
     674         [ #  # ]:          0 :         for_each_available_child_of_node(opp_table->np, np) {
     675                 :          0 :                 opp = _opp_add_static_v2(opp_table, dev, np);
     676         [ #  # ]:          0 :                 if (IS_ERR(opp)) {
     677                 :            :                         ret = PTR_ERR(opp);
     678                 :          0 :                         dev_err(dev, "%s: Failed to add OPP, %d\n", __func__,
     679                 :            :                                 ret);
     680                 :          0 :                         of_node_put(np);
     681                 :          0 :                         goto put_list_kref;
     682         [ #  # ]:          0 :                 } else if (opp) {
     683                 :          0 :                         count++;
     684                 :            :                 }
     685                 :            :         }
     686                 :            : 
     687                 :            :         /* There should be one of more OPP defined */
     688   [ #  #  #  # ]:          0 :         if (WARN_ON(!count)) {
     689                 :            :                 ret = -ENOENT;
     690                 :            :                 goto put_list_kref;
     691                 :            :         }
     692                 :            : 
     693         [ #  # ]:          0 :         list_for_each_entry(opp, &opp_table->opp_list, node)
     694                 :          0 :                 pstate_count += !!opp->pstate;
     695                 :            : 
     696                 :            :         /* Either all or none of the nodes shall have performance state set */
     697         [ #  # ]:          0 :         if (pstate_count && pstate_count != count) {
     698                 :          0 :                 dev_err(dev, "Not all nodes have performance state set (%d: %d)\n",
     699                 :            :                         count, pstate_count);
     700                 :            :                 ret = -ENOENT;
     701                 :          0 :                 goto put_list_kref;
     702                 :            :         }
     703                 :            : 
     704         [ #  # ]:          0 :         if (pstate_count)
     705                 :          0 :                 opp_table->genpd_performance_state = true;
     706                 :            : 
     707                 :          0 :         opp_table->parsed_static_opps = true;
     708                 :            : 
     709                 :          0 :         return 0;
     710                 :            : 
     711                 :            : put_list_kref:
     712                 :          0 :         _put_opp_list_kref(opp_table);
     713                 :            : 
     714                 :          0 :         return ret;
     715                 :            : }
     716                 :            : 
     717                 :            : /* Initializes OPP tables based on old-deprecated bindings */
     718                 :          0 : static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
     719                 :            : {
     720                 :            :         const struct property *prop;
     721                 :            :         const __be32 *val;
     722                 :            :         int nr, ret = 0;
     723                 :            : 
     724                 :          0 :         prop = of_find_property(dev->of_node, "operating-points", NULL);
     725         [ #  # ]:          0 :         if (!prop)
     726                 :            :                 return -ENODEV;
     727         [ #  # ]:          0 :         if (!prop->value)
     728                 :            :                 return -ENODATA;
     729                 :            : 
     730                 :            :         /*
     731                 :            :          * Each OPP is a set of tuples consisting of frequency and
     732                 :            :          * voltage like <freq-kHz vol-uV>.
     733                 :            :          */
     734                 :          0 :         nr = prop->length / sizeof(u32);
     735         [ #  # ]:          0 :         if (nr % 2) {
     736                 :          0 :                 dev_err(dev, "%s: Invalid OPP table\n", __func__);
     737                 :          0 :                 return -EINVAL;
     738                 :            :         }
     739                 :            : 
     740                 :            :         val = prop->value;
     741         [ #  # ]:          0 :         while (nr) {
     742                 :          0 :                 unsigned long freq = be32_to_cpup(val++) * 1000;
     743                 :          0 :                 unsigned long volt = be32_to_cpup(val++);
     744                 :            : 
     745                 :          0 :                 ret = _opp_add_v1(opp_table, dev, freq, volt, false);
     746         [ #  # ]:          0 :                 if (ret) {
     747                 :          0 :                         dev_err(dev, "%s: Failed to add OPP %ld (%d)\n",
     748                 :            :                                 __func__, freq, ret);
     749                 :          0 :                         _put_opp_list_kref(opp_table);
     750                 :          0 :                         return ret;
     751                 :            :                 }
     752                 :          0 :                 nr -= 2;
     753                 :            :         }
     754                 :            : 
     755                 :          0 :         return ret;
     756                 :            : }
     757                 :            : 
     758                 :            : /**
     759                 :            :  * dev_pm_opp_of_add_table() - Initialize opp table from device tree
     760                 :            :  * @dev:        device pointer used to lookup OPP table.
     761                 :            :  *
     762                 :            :  * Register the initial OPP table with the OPP library for given device.
     763                 :            :  *
     764                 :            :  * Return:
     765                 :            :  * 0            On success OR
     766                 :            :  *              Duplicate OPPs (both freq and volt are same) and opp->available
     767                 :            :  * -EEXIST      Freq are same and volt are different OR
     768                 :            :  *              Duplicate OPPs (both freq and volt are same) and !opp->available
     769                 :            :  * -ENOMEM      Memory allocation failure
     770                 :            :  * -ENODEV      when 'operating-points' property is not found or is invalid data
     771                 :            :  *              in device node.
     772                 :            :  * -ENODATA     when empty 'operating-points' property is found
     773                 :            :  * -EINVAL      when invalid entries are found in opp-v2 table
     774                 :            :  */
     775                 :          0 : int dev_pm_opp_of_add_table(struct device *dev)
     776                 :            : {
     777                 :            :         struct opp_table *opp_table;
     778                 :            :         int ret;
     779                 :            : 
     780                 :          0 :         opp_table = dev_pm_opp_get_opp_table_indexed(dev, 0);
     781         [ #  # ]:          0 :         if (!opp_table)
     782                 :            :                 return -ENOMEM;
     783                 :            : 
     784                 :            :         /*
     785                 :            :          * OPPs have two version of bindings now. Also try the old (v1)
     786                 :            :          * bindings for backward compatibility with older dtbs.
     787                 :            :          */
     788         [ #  # ]:          0 :         if (opp_table->np)
     789                 :          0 :                 ret = _of_add_opp_table_v2(dev, opp_table);
     790                 :            :         else
     791                 :          0 :                 ret = _of_add_opp_table_v1(dev, opp_table);
     792                 :            : 
     793         [ #  # ]:          0 :         if (ret)
     794                 :          0 :                 dev_pm_opp_put_opp_table(opp_table);
     795                 :            : 
     796                 :          0 :         return ret;
     797                 :            : }
     798                 :            : EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table);
     799                 :            : 
     800                 :            : /**
     801                 :            :  * dev_pm_opp_of_add_table_indexed() - Initialize indexed opp table from device tree
     802                 :            :  * @dev:        device pointer used to lookup OPP table.
     803                 :            :  * @index:      Index number.
     804                 :            :  *
     805                 :            :  * Register the initial OPP table with the OPP library for given device only
     806                 :            :  * using the "operating-points-v2" property.
     807                 :            :  *
     808                 :            :  * Return:
     809                 :            :  * 0            On success OR
     810                 :            :  *              Duplicate OPPs (both freq and volt are same) and opp->available
     811                 :            :  * -EEXIST      Freq are same and volt are different OR
     812                 :            :  *              Duplicate OPPs (both freq and volt are same) and !opp->available
     813                 :            :  * -ENOMEM      Memory allocation failure
     814                 :            :  * -ENODEV      when 'operating-points' property is not found or is invalid data
     815                 :            :  *              in device node.
     816                 :            :  * -ENODATA     when empty 'operating-points' property is found
     817                 :            :  * -EINVAL      when invalid entries are found in opp-v2 table
     818                 :            :  */
     819                 :          0 : int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
     820                 :            : {
     821                 :            :         struct opp_table *opp_table;
     822                 :            :         int ret, count;
     823                 :            : 
     824         [ #  # ]:          0 :         if (index) {
     825                 :            :                 /*
     826                 :            :                  * If only one phandle is present, then the same OPP table
     827                 :            :                  * applies for all index requests.
     828                 :            :                  */
     829                 :          0 :                 count = of_count_phandle_with_args(dev->of_node,
     830                 :            :                                                    "operating-points-v2", NULL);
     831         [ #  # ]:          0 :                 if (count == 1)
     832                 :            :                         index = 0;
     833                 :            :         }
     834                 :            : 
     835                 :          0 :         opp_table = dev_pm_opp_get_opp_table_indexed(dev, index);
     836         [ #  # ]:          0 :         if (!opp_table)
     837                 :            :                 return -ENOMEM;
     838                 :            : 
     839                 :          0 :         ret = _of_add_opp_table_v2(dev, opp_table);
     840         [ #  # ]:          0 :         if (ret)
     841                 :          0 :                 dev_pm_opp_put_opp_table(opp_table);
     842                 :            : 
     843                 :          0 :         return ret;
     844                 :            : }
     845                 :            : EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table_indexed);
     846                 :            : 
     847                 :            : /* CPU device specific helpers */
     848                 :            : 
     849                 :            : /**
     850                 :            :  * dev_pm_opp_of_cpumask_remove_table() - Removes OPP table for @cpumask
     851                 :            :  * @cpumask:    cpumask for which OPP table needs to be removed
     852                 :            :  *
     853                 :            :  * This removes the OPP tables for CPUs present in the @cpumask.
     854                 :            :  * This should be used only to remove static entries created from DT.
     855                 :            :  */
     856                 :          0 : void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask)
     857                 :            : {
     858                 :          0 :         _dev_pm_opp_cpumask_remove_table(cpumask, -1);
     859                 :          0 : }
     860                 :            : EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_remove_table);
     861                 :            : 
     862                 :            : /**
     863                 :            :  * dev_pm_opp_of_cpumask_add_table() - Adds OPP table for @cpumask
     864                 :            :  * @cpumask:    cpumask for which OPP table needs to be added.
     865                 :            :  *
     866                 :            :  * This adds the OPP tables for CPUs present in the @cpumask.
     867                 :            :  */
     868                 :          0 : int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask)
     869                 :            : {
     870                 :            :         struct device *cpu_dev;
     871                 :            :         int cpu, ret;
     872                 :            : 
     873   [ #  #  #  # ]:          0 :         if (WARN_ON(cpumask_empty(cpumask)))
     874                 :            :                 return -ENODEV;
     875                 :            : 
     876         [ #  # ]:          0 :         for_each_cpu(cpu, cpumask) {
     877                 :          0 :                 cpu_dev = get_cpu_device(cpu);
     878         [ #  # ]:          0 :                 if (!cpu_dev) {
     879                 :          0 :                         pr_err("%s: failed to get cpu%d device\n", __func__,
     880                 :            :                                cpu);
     881                 :            :                         ret = -ENODEV;
     882                 :          0 :                         goto remove_table;
     883                 :            :                 }
     884                 :            : 
     885                 :          0 :                 ret = dev_pm_opp_of_add_table(cpu_dev);
     886         [ #  # ]:          0 :                 if (ret) {
     887                 :            :                         /*
     888                 :            :                          * OPP may get registered dynamically, don't print error
     889                 :            :                          * message here.
     890                 :            :                          */
     891                 :            :                         pr_debug("%s: couldn't find opp table for cpu:%d, %d\n",
     892                 :            :                                  __func__, cpu, ret);
     893                 :            : 
     894                 :            :                         goto remove_table;
     895                 :            :                 }
     896                 :            :         }
     897                 :            : 
     898                 :            :         return 0;
     899                 :            : 
     900                 :            : remove_table:
     901                 :            :         /* Free all other OPPs */
     902                 :          0 :         _dev_pm_opp_cpumask_remove_table(cpumask, cpu);
     903                 :            : 
     904                 :          0 :         return ret;
     905                 :            : }
     906                 :            : EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_add_table);
     907                 :            : 
     908                 :            : /*
     909                 :            :  * Works only for OPP v2 bindings.
     910                 :            :  *
     911                 :            :  * Returns -ENOENT if operating-points-v2 bindings aren't supported.
     912                 :            :  */
     913                 :            : /**
     914                 :            :  * dev_pm_opp_of_get_sharing_cpus() - Get cpumask of CPUs sharing OPPs with
     915                 :            :  *                                    @cpu_dev using operating-points-v2
     916                 :            :  *                                    bindings.
     917                 :            :  *
     918                 :            :  * @cpu_dev:    CPU device for which we do this operation
     919                 :            :  * @cpumask:    cpumask to update with information of sharing CPUs
     920                 :            :  *
     921                 :            :  * This updates the @cpumask with CPUs that are sharing OPPs with @cpu_dev.
     922                 :            :  *
     923                 :            :  * Returns -ENOENT if operating-points-v2 isn't present for @cpu_dev.
     924                 :            :  */
     925                 :          0 : int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev,
     926                 :            :                                    struct cpumask *cpumask)
     927                 :            : {
     928                 :            :         struct device_node *np, *tmp_np, *cpu_np;
     929                 :            :         int cpu, ret = 0;
     930                 :            : 
     931                 :            :         /* Get OPP descriptor node */
     932                 :            :         np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
     933         [ #  # ]:          0 :         if (!np) {
     934                 :            :                 dev_dbg(cpu_dev, "%s: Couldn't find opp node.\n", __func__);
     935                 :            :                 return -ENOENT;
     936                 :            :         }
     937                 :            : 
     938                 :          0 :         cpumask_set_cpu(cpu_dev->id, cpumask);
     939                 :            : 
     940                 :            :         /* OPPs are shared ? */
     941         [ #  # ]:          0 :         if (!of_property_read_bool(np, "opp-shared"))
     942                 :            :                 goto put_cpu_node;
     943                 :            : 
     944         [ #  # ]:          0 :         for_each_possible_cpu(cpu) {
     945         [ #  # ]:          0 :                 if (cpu == cpu_dev->id)
     946                 :          0 :                         continue;
     947                 :            : 
     948                 :          0 :                 cpu_np = of_cpu_device_node_get(cpu);
     949         [ #  # ]:          0 :                 if (!cpu_np) {
     950                 :          0 :                         dev_err(cpu_dev, "%s: failed to get cpu%d node\n",
     951                 :            :                                 __func__, cpu);
     952                 :            :                         ret = -ENOENT;
     953                 :          0 :                         goto put_cpu_node;
     954                 :            :                 }
     955                 :            : 
     956                 :            :                 /* Get OPP descriptor node */
     957                 :            :                 tmp_np = _opp_of_get_opp_desc_node(cpu_np, 0);
     958                 :          0 :                 of_node_put(cpu_np);
     959         [ #  # ]:          0 :                 if (!tmp_np) {
     960                 :          0 :                         pr_err("%pOF: Couldn't find opp node\n", cpu_np);
     961                 :            :                         ret = -ENOENT;
     962                 :          0 :                         goto put_cpu_node;
     963                 :            :                 }
     964                 :            : 
     965                 :            :                 /* CPUs are sharing opp node */
     966         [ #  # ]:          0 :                 if (np == tmp_np)
     967                 :            :                         cpumask_set_cpu(cpu, cpumask);
     968                 :            : 
     969                 :          0 :                 of_node_put(tmp_np);
     970                 :            :         }
     971                 :            : 
     972                 :            : put_cpu_node:
     973                 :          0 :         of_node_put(np);
     974                 :          0 :         return ret;
     975                 :            : }
     976                 :            : EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_sharing_cpus);
     977                 :            : 
     978                 :            : /**
     979                 :            :  * of_get_required_opp_performance_state() - Search for required OPP and return its performance state.
     980                 :            :  * @np: Node that contains the "required-opps" property.
     981                 :            :  * @index: Index of the phandle to parse.
     982                 :            :  *
     983                 :            :  * Returns the performance state of the OPP pointed out by the "required-opps"
     984                 :            :  * property at @index in @np.
     985                 :            :  *
     986                 :            :  * Return: Zero or positive performance state on success, otherwise negative
     987                 :            :  * value on errors.
     988                 :            :  */
     989                 :          0 : int of_get_required_opp_performance_state(struct device_node *np, int index)
     990                 :            : {
     991                 :            :         struct dev_pm_opp *opp;
     992                 :            :         struct device_node *required_np;
     993                 :            :         struct opp_table *opp_table;
     994                 :            :         int pstate = -EINVAL;
     995                 :            : 
     996                 :          0 :         required_np = of_parse_required_opp(np, index);
     997         [ #  # ]:          0 :         if (!required_np)
     998                 :            :                 return -EINVAL;
     999                 :            : 
    1000                 :          0 :         opp_table = _find_table_of_opp_np(required_np);
    1001         [ #  # ]:          0 :         if (IS_ERR(opp_table)) {
    1002                 :          0 :                 pr_err("%s: Failed to find required OPP table %pOF: %ld\n",
    1003                 :            :                        __func__, np, PTR_ERR(opp_table));
    1004                 :          0 :                 goto put_required_np;
    1005                 :            :         }
    1006                 :            : 
    1007                 :          0 :         opp = _find_opp_of_np(opp_table, required_np);
    1008         [ #  # ]:          0 :         if (opp) {
    1009                 :          0 :                 pstate = opp->pstate;
    1010                 :          0 :                 dev_pm_opp_put(opp);
    1011                 :            :         }
    1012                 :            : 
    1013                 :          0 :         dev_pm_opp_put_opp_table(opp_table);
    1014                 :            : 
    1015                 :            : put_required_np:
    1016                 :          0 :         of_node_put(required_np);
    1017                 :            : 
    1018                 :          0 :         return pstate;
    1019                 :            : }
    1020                 :            : EXPORT_SYMBOL_GPL(of_get_required_opp_performance_state);
    1021                 :            : 
    1022                 :            : /**
    1023                 :            :  * dev_pm_opp_get_of_node() - Gets the DT node corresponding to an opp
    1024                 :            :  * @opp:        opp for which DT node has to be returned for
    1025                 :            :  *
    1026                 :            :  * Return: DT node corresponding to the opp, else 0 on success.
    1027                 :            :  *
    1028                 :            :  * The caller needs to put the node with of_node_put() after using it.
    1029                 :            :  */
    1030                 :          0 : struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp)
    1031                 :            : {
    1032         [ #  # ]:          0 :         if (IS_ERR_OR_NULL(opp)) {
    1033                 :          0 :                 pr_err("%s: Invalid parameters\n", __func__);
    1034                 :          0 :                 return NULL;
    1035                 :            :         }
    1036                 :            : 
    1037                 :          0 :         return of_node_get(opp->np);
    1038                 :            : }
    1039                 :            : EXPORT_SYMBOL_GPL(dev_pm_opp_get_of_node);
    1040                 :            : 
    1041                 :            : /*
    1042                 :            :  * Callback function provided to the Energy Model framework upon registration.
    1043                 :            :  * This computes the power estimated by @CPU at @kHz if it is the frequency
    1044                 :            :  * of an existing OPP, or at the frequency of the first OPP above @kHz otherwise
    1045                 :            :  * (see dev_pm_opp_find_freq_ceil()). This function updates @kHz to the ceiled
    1046                 :            :  * frequency and @mW to the associated power. The power is estimated as
    1047                 :            :  * P = C * V^2 * f with C being the CPU's capacitance and V and f respectively
    1048                 :            :  * the voltage and frequency of the OPP.
    1049                 :            :  *
    1050                 :            :  * Returns -ENODEV if the CPU device cannot be found, -EINVAL if the power
    1051                 :            :  * calculation failed because of missing parameters, 0 otherwise.
    1052                 :            :  */
    1053                 :            : static int __maybe_unused _get_cpu_power(unsigned long *mW, unsigned long *kHz,
    1054                 :            :                                          int cpu)
    1055                 :            : {
    1056                 :            :         struct device *cpu_dev;
    1057                 :            :         struct dev_pm_opp *opp;
    1058                 :            :         struct device_node *np;
    1059                 :            :         unsigned long mV, Hz;
    1060                 :            :         u32 cap;
    1061                 :            :         u64 tmp;
    1062                 :            :         int ret;
    1063                 :            : 
    1064                 :            :         cpu_dev = get_cpu_device(cpu);
    1065                 :            :         if (!cpu_dev)
    1066                 :            :                 return -ENODEV;
    1067                 :            : 
    1068                 :            :         np = of_node_get(cpu_dev->of_node);
    1069                 :            :         if (!np)
    1070                 :            :                 return -EINVAL;
    1071                 :            : 
    1072                 :            :         ret = of_property_read_u32(np, "dynamic-power-coefficient", &cap);
    1073                 :            :         of_node_put(np);
    1074                 :            :         if (ret)
    1075                 :            :                 return -EINVAL;
    1076                 :            : 
    1077                 :            :         Hz = *kHz * 1000;
    1078                 :            :         opp = dev_pm_opp_find_freq_ceil(cpu_dev, &Hz);
    1079                 :            :         if (IS_ERR(opp))
    1080                 :            :                 return -EINVAL;
    1081                 :            : 
    1082                 :            :         mV = dev_pm_opp_get_voltage(opp) / 1000;
    1083                 :            :         dev_pm_opp_put(opp);
    1084                 :            :         if (!mV)
    1085                 :            :                 return -EINVAL;
    1086                 :            : 
    1087                 :            :         tmp = (u64)cap * mV * mV * (Hz / 1000000);
    1088                 :            :         do_div(tmp, 1000000000);
    1089                 :            : 
    1090                 :            :         *mW = (unsigned long)tmp;
    1091                 :            :         *kHz = Hz / 1000;
    1092                 :            : 
    1093                 :            :         return 0;
    1094                 :            : }
    1095                 :            : 
    1096                 :            : /**
    1097                 :            :  * dev_pm_opp_of_register_em() - Attempt to register an Energy Model
    1098                 :            :  * @cpus        : CPUs for which an Energy Model has to be registered
    1099                 :            :  *
    1100                 :            :  * This checks whether the "dynamic-power-coefficient" devicetree property has
    1101                 :            :  * been specified, and tries to register an Energy Model with it if it has.
    1102                 :            :  */
    1103                 :          0 : void dev_pm_opp_of_register_em(struct cpumask *cpus)
    1104                 :            : {
    1105                 :            :         struct em_data_callback em_cb = EM_DATA_CB(_get_cpu_power);
    1106                 :            :         int ret, nr_opp, cpu = cpumask_first(cpus);
    1107                 :            :         struct device *cpu_dev;
    1108                 :            :         struct device_node *np;
    1109                 :            :         u32 cap;
    1110                 :            : 
    1111                 :          0 :         cpu_dev = get_cpu_device(cpu);
    1112         [ #  # ]:          0 :         if (!cpu_dev)
    1113                 :          0 :                 return;
    1114                 :            : 
    1115                 :          0 :         nr_opp = dev_pm_opp_get_opp_count(cpu_dev);
    1116         [ #  # ]:          0 :         if (nr_opp <= 0)
    1117                 :            :                 return;
    1118                 :            : 
    1119                 :          0 :         np = of_node_get(cpu_dev->of_node);
    1120         [ #  # ]:          0 :         if (!np)
    1121                 :            :                 return;
    1122                 :            : 
    1123                 :            :         /*
    1124                 :            :          * Register an EM only if the 'dynamic-power-coefficient' property is
    1125                 :            :          * set in devicetree. It is assumed the voltage values are known if that
    1126                 :            :          * property is set since it is useless otherwise. If voltages are not
    1127                 :            :          * known, just let the EM registration fail with an error to alert the
    1128                 :            :          * user about the inconsistent configuration.
    1129                 :            :          */
    1130                 :            :         ret = of_property_read_u32(np, "dynamic-power-coefficient", &cap);
    1131                 :          0 :         of_node_put(np);
    1132   [ #  #  #  # ]:          0 :         if (ret || !cap)
    1133                 :            :                 return;
    1134                 :            : 
    1135                 :            :         em_register_perf_domain(cpus, nr_opp, &em_cb);
    1136                 :            : }
    1137                 :            : EXPORT_SYMBOL_GPL(dev_pm_opp_of_register_em);

Generated by: LCOV version 1.14