return ret;
        }
 
+       if (opp_table->get_pstate)
+               new_opp->pstate = opp_table->get_pstate(dev, new_opp->rate);
+
        list_add(&new_opp->node, head);
        mutex_unlock(&opp_table->lock);
 
 }
 EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_set_opp_helper);
 
+/**
+ * dev_pm_opp_register_get_pstate_helper() - Register get_pstate() helper.
+ * @dev: Device for which the helper is getting registered.
+ * @get_pstate: Helper.
+ *
+ * TODO: Remove this callback after the same information is available via Device
+ * Tree.
+ *
+ * This allows a platform to initialize the performance states of individual
+ * OPPs for its devices, until we get similar information directly from DT.
+ *
+ * This must be called before the OPPs are initialized for the device.
+ */
+struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev,
+               int (*get_pstate)(struct device *dev, unsigned long rate))
+{
+       struct opp_table *opp_table;
+       int ret;
+
+       if (!get_pstate)
+               return ERR_PTR(-EINVAL);
+
+       opp_table = dev_pm_opp_get_opp_table(dev);
+       if (!opp_table)
+               return ERR_PTR(-ENOMEM);
+
+       /* This should be called before OPPs are initialized */
+       if (WARN_ON(!list_empty(&opp_table->opp_list))) {
+               ret = -EBUSY;
+               goto err;
+       }
+
+       /* Already have genpd_performance_state set */
+       if (WARN_ON(opp_table->genpd_performance_state)) {
+               ret = -EBUSY;
+               goto err;
+       }
+
+       opp_table->genpd_performance_state = true;
+       opp_table->get_pstate = get_pstate;
+
+       return opp_table;
+
+err:
+       dev_pm_opp_put_opp_table(opp_table);
+
+       return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(dev_pm_opp_register_get_pstate_helper);
+
+/**
+ * dev_pm_opp_unregister_get_pstate_helper() - Releases resources blocked for
+ *                                        get_pstate() helper
+ * @opp_table: OPP table returned from dev_pm_opp_register_get_pstate_helper().
+ *
+ * Release resources blocked for platform specific get_pstate() helper.
+ */
+void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table)
+{
+       if (!opp_table->genpd_performance_state) {
+               pr_err("%s: Doesn't have performance states set\n",
+                      __func__);
+               return;
+       }
+
+       /* Make sure there are no concurrent readers while updating opp_table */
+       WARN_ON(!list_empty(&opp_table->opp_list));
+
+       opp_table->genpd_performance_state = false;
+       opp_table->get_pstate = NULL;
+
+       dev_pm_opp_put_opp_table(opp_table);
+}
+EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_get_pstate_helper);
+
 /**
  * dev_pm_opp_add()  - Add an OPP table from a table definitions
  * @dev:       device for which we do this operation
 
  * @genpd_performance_state: Device's power domain support performance state.
  * @set_opp: Platform specific set_opp callback
  * @set_opp_data: Data to be passed to set_opp callback
+ * @get_pstate: Platform specific get_pstate callback
  * @dentry:    debugfs dentry pointer of the real device directory (not links).
  * @dentry_name: Name of the real dentry.
  *
 
        int (*set_opp)(struct dev_pm_set_opp_data *data);
        struct dev_pm_set_opp_data *set_opp_data;
+       int (*get_pstate)(struct device *dev, unsigned long rate);
 
 #ifdef CONFIG_DEBUG_FS
        struct dentry *dentry;
 
 void dev_pm_opp_put_clkname(struct opp_table *opp_table);
 struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
 void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table);
+struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev, int (*get_pstate)(struct device *dev, unsigned long rate));
+void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table);
 int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
 int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
 int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
 
 static inline void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) {}
 
+static inline struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev,
+               int (*get_pstate)(struct device *dev, unsigned long rate))
+{
+       return ERR_PTR(-ENOTSUPP);
+}
+
+static inline void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table) {}
+
 static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name)
 {
        return ERR_PTR(-ENOTSUPP);