}
 EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil_by_volt);
 
+/**
+ * dev_pm_opp_find_bw_ceil() - Search for a rounded ceil bandwidth
+ * @dev:       device for which we do this operation
+ * @freq:      start bandwidth
+ * @index:     which bandwidth to compare, in case of OPPs with several values
+ *
+ * Search for the matching floor *available* OPP from a starting bandwidth
+ * for a device.
+ *
+ * Return: matching *opp and refreshes *bw accordingly, else returns
+ * ERR_PTR in case of error and should be handled using IS_ERR. Error return
+ * values can be:
+ * EINVAL:     for bad pointer
+ * ERANGE:     no match found for search
+ * ENODEV:     if device not found in list of registered devices
+ *
+ * The callers are required to call dev_pm_opp_put() for the returned OPP after
+ * use.
+ */
+struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev,
+                                          unsigned int *bw, int index)
+{
+       struct opp_table *opp_table;
+       struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE);
+
+       if (!dev || !bw) {
+               dev_err(dev, "%s: Invalid argument bw=%p\n", __func__, bw);
+               return ERR_PTR(-EINVAL);
+       }
+
+       opp_table = _find_opp_table(dev);
+       if (IS_ERR(opp_table))
+               return ERR_CAST(opp_table);
+
+       if (index >= opp_table->path_count)
+               return ERR_PTR(-EINVAL);
+
+       mutex_lock(&opp_table->lock);
+
+       list_for_each_entry(temp_opp, &opp_table->opp_list, node) {
+               if (temp_opp->available && temp_opp->bandwidth) {
+                       if (temp_opp->bandwidth[index].peak >= *bw) {
+                               opp = temp_opp;
+                               *bw = opp->bandwidth[index].peak;
+
+                               /* Increment the reference count of OPP */
+                               dev_pm_opp_get(opp);
+                               break;
+                       }
+               }
+       }
+
+       mutex_unlock(&opp_table->lock);
+       dev_pm_opp_put_opp_table(opp_table);
+
+       return opp;
+}
+EXPORT_SYMBOL_GPL(dev_pm_opp_find_bw_ceil);
+
+/**
+ * dev_pm_opp_find_bw_floor() - Search for a rounded floor bandwidth
+ * @dev:       device for which we do this operation
+ * @freq:      start bandwidth
+ * @index:     which bandwidth to compare, in case of OPPs with several values
+ *
+ * Search for the matching floor *available* OPP from a starting bandwidth
+ * for a device.
+ *
+ * Return: matching *opp and refreshes *bw accordingly, else returns
+ * ERR_PTR in case of error and should be handled using IS_ERR. Error return
+ * values can be:
+ * EINVAL:     for bad pointer
+ * ERANGE:     no match found for search
+ * ENODEV:     if device not found in list of registered devices
+ *
+ * The callers are required to call dev_pm_opp_put() for the returned OPP after
+ * use.
+ */
+struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev,
+                                           unsigned int *bw, int index)
+{
+       struct opp_table *opp_table;
+       struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE);
+
+       if (!dev || !bw) {
+               dev_err(dev, "%s: Invalid argument bw=%p\n", __func__, bw);
+               return ERR_PTR(-EINVAL);
+       }
+
+       opp_table = _find_opp_table(dev);
+       if (IS_ERR(opp_table))
+               return ERR_CAST(opp_table);
+
+       if (index >= opp_table->path_count)
+               return ERR_PTR(-EINVAL);
+
+       mutex_lock(&opp_table->lock);
+
+       list_for_each_entry(temp_opp, &opp_table->opp_list, node) {
+               if (temp_opp->available && temp_opp->bandwidth) {
+                       /* go to the next node, before choosing prev */
+                       if (temp_opp->bandwidth[index].peak > *bw)
+                               break;
+                       opp = temp_opp;
+               }
+       }
+
+       /* Increment the reference count of OPP */
+       if (!IS_ERR(opp))
+               dev_pm_opp_get(opp);
+       mutex_unlock(&opp_table->lock);
+       dev_pm_opp_put_opp_table(opp_table);
+
+       if (!IS_ERR(opp))
+               *bw = opp->bandwidth[index].peak;
+
+       return opp;
+}
+EXPORT_SYMBOL_GPL(dev_pm_opp_find_bw_floor);
+
 static int _set_opp_voltage(struct device *dev, struct regulator *reg,
                            struct dev_pm_opp_supply *supply)
 {
 
 
 struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev,
                                             unsigned long *freq);
+
+struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev,
+                                          unsigned int *bw, int index);
+
+struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev,
+                                          unsigned int *bw, int index);
+
 void dev_pm_opp_put(struct dev_pm_opp *opp);
 
 int dev_pm_opp_add(struct device *dev, unsigned long freq,
        return ERR_PTR(-EOPNOTSUPP);
 }
 
+static inline struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev,
+                                       unsigned int *bw, int index)
+{
+       return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev,
+                                       unsigned int *bw, int index)
+{
+       return ERR_PTR(-EOPNOTSUPP);
+}
+
 static inline void dev_pm_opp_put(struct dev_pm_opp *opp) {}
 
 static inline int dev_pm_opp_add(struct device *dev, unsigned long freq,