_of_init_opp_table(opp_table, dev, index);
 
-       /* Find clk for the device */
-       opp_table->clk = clk_get(dev, NULL);
-       if (IS_ERR(opp_table->clk)) {
-               ret = PTR_ERR(opp_table->clk);
-               if (ret == -EPROBE_DEFER)
-                       goto remove_opp_dev;
-
-               dev_dbg(dev, "%s: Couldn't find clock: %d\n", __func__, ret);
-       }
-
        /* Find interconnect path(s) for the device */
        ret = dev_pm_opp_of_find_icc_paths(dev, opp_table);
        if (ret) {
                if (ret == -EPROBE_DEFER)
-                       goto put_clk;
+                       goto remove_opp_dev;
 
                dev_warn(dev, "%s: Error finding interconnect paths: %d\n",
                         __func__, ret);
 
        return opp_table;
 
-put_clk:
-       if (!IS_ERR(opp_table->clk))
-               clk_put(opp_table->clk);
 remove_opp_dev:
        _remove_opp_dev(opp_dev, opp_table);
 err:
        kref_get(&opp_table->kref);
 }
 
+static struct opp_table *_update_opp_table_clk(struct device *dev,
+                                              struct opp_table *opp_table,
+                                              bool getclk)
+{
+       /*
+        * Return early if we don't need to get clk or we have already tried it
+        * earlier.
+        */
+       if (!getclk || IS_ERR(opp_table) || opp_table->clk)
+               return opp_table;
+
+       /* Find clk for the device */
+       opp_table->clk = clk_get(dev, NULL);
+       if (IS_ERR(opp_table->clk)) {
+               int ret = PTR_ERR(opp_table->clk);
+
+               if (ret == -EPROBE_DEFER) {
+                       dev_pm_opp_put_opp_table(opp_table);
+                       return ERR_PTR(ret);
+               }
+
+               dev_dbg(dev, "%s: Couldn't find clock: %d\n", __func__, ret);
+       }
+
+       return opp_table;
+}
+
 /*
  * We need to make sure that the OPP table for a device doesn't get added twice,
  * if this routine gets called in parallel with the same device pointer.
  * uses the opp_tables_busy flag to indicate if another creator is in the middle
  * of adding an OPP table and others should wait for it to finish.
  */
-struct opp_table *_add_opp_table_indexed(struct device *dev, int index)
+struct opp_table *_add_opp_table_indexed(struct device *dev, int index,
+                                        bool getclk)
 {
        struct opp_table *opp_table;
 
 unlock:
        mutex_unlock(&opp_table_lock);
 
-       return opp_table;
+       return _update_opp_table_clk(dev, opp_table, getclk);
 }
 
-static struct opp_table *_add_opp_table(struct device *dev)
+static struct opp_table *_add_opp_table(struct device *dev, bool getclk)
 {
-       return _add_opp_table_indexed(dev, 0);
+       return _add_opp_table_indexed(dev, 0, getclk);
 }
 
 struct opp_table *dev_pm_opp_get_opp_table(struct device *dev)
 {
        struct opp_table *opp_table;
 
-       opp_table = _add_opp_table(dev);
+       opp_table = _add_opp_table(dev, false);
        if (IS_ERR(opp_table))
                return opp_table;
 
 {
        struct opp_table *opp_table;
 
-       opp_table = _add_opp_table(dev);
+       opp_table = _add_opp_table(dev, false);
        if (IS_ERR(opp_table))
                return opp_table;
 
        struct regulator *reg;
        int ret, i;
 
-       opp_table = _add_opp_table(dev);
+       opp_table = _add_opp_table(dev, false);
        if (IS_ERR(opp_table))
                return opp_table;
 
        struct opp_table *opp_table;
        int ret;
 
-       opp_table = _add_opp_table(dev);
+       opp_table = _add_opp_table(dev, false);
        if (IS_ERR(opp_table))
                return opp_table;
 
                goto err;
        }
 
-       /* Already have default clk set, free it */
-       if (!IS_ERR(opp_table->clk))
-               clk_put(opp_table->clk);
+       /* clk shouldn't be initialized at this point */
+       if (WARN_ON(opp_table->clk)) {
+               ret = -EBUSY;
+               goto err;
+       }
 
        /* Find clk for the device */
        opp_table->clk = clk_get(dev, name);
        if (!set_opp)
                return ERR_PTR(-EINVAL);
 
-       opp_table = _add_opp_table(dev);
+       opp_table = _add_opp_table(dev, false);
        if (IS_ERR(opp_table))
                return opp_table;
 
        int index = 0, ret = -EINVAL;
        const char **name = names;
 
-       opp_table = _add_opp_table(dev);
+       opp_table = _add_opp_table(dev, false);
        if (IS_ERR(opp_table))
                return opp_table;
 
        struct opp_table *opp_table;
        int ret;
 
-       opp_table = _add_opp_table(dev);
+       opp_table = _add_opp_table(dev, true);
        if (IS_ERR(opp_table))
                return PTR_ERR(opp_table);
 
 
        return ret;
 }
 
-static int _of_add_table_indexed(struct device *dev, int index)
+static int _of_add_table_indexed(struct device *dev, int index, bool getclk)
 {
        struct opp_table *opp_table;
        int ret, count;
                        index = 0;
        }
 
-       opp_table = _add_opp_table_indexed(dev, index);
+       opp_table = _add_opp_table_indexed(dev, index, getclk);
        if (IS_ERR(opp_table))
                return PTR_ERR(opp_table);
 
  */
 int dev_pm_opp_of_add_table(struct device *dev)
 {
-       return _of_add_table_indexed(dev, 0);
+       return _of_add_table_indexed(dev, 0, true);
 }
 EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table);
 
  */
 int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
 {
-       return _of_add_table_indexed(dev, index);
+       return _of_add_table_indexed(dev, index, true);
 }
 EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table_indexed);