@@ -729,6 +729,126 @@ struct dev_pm_opp *dev_pm_opp_find_freq_ceil_by_volt(struct device *dev,
729729}
730730EXPORT_SYMBOL_GPL (dev_pm_opp_find_freq_ceil_by_volt );
731731
732+ /**
733+ * dev_pm_opp_find_bw_ceil() - Search for a rounded ceil bandwidth
734+ * @dev: device for which we do this operation
735+ * @freq: start bandwidth
736+ * @index: which bandwidth to compare, in case of OPPs with several values
737+ *
738+ * Search for the matching floor *available* OPP from a starting bandwidth
739+ * for a device.
740+ *
741+ * Return: matching *opp and refreshes *bw accordingly, else returns
742+ * ERR_PTR in case of error and should be handled using IS_ERR. Error return
743+ * values can be:
744+ * EINVAL: for bad pointer
745+ * ERANGE: no match found for search
746+ * ENODEV: if device not found in list of registered devices
747+ *
748+ * The callers are required to call dev_pm_opp_put() for the returned OPP after
749+ * use.
750+ */
751+ struct dev_pm_opp * dev_pm_opp_find_bw_ceil (struct device * dev ,
752+ unsigned int * bw , int index )
753+ {
754+ struct opp_table * opp_table ;
755+ struct dev_pm_opp * temp_opp , * opp = ERR_PTR (- ERANGE );
756+
757+ if (!dev || !bw ) {
758+ dev_err (dev , "%s: Invalid argument bw=%p\n" , __func__ , bw );
759+ return ERR_PTR (- EINVAL );
760+ }
761+
762+ opp_table = _find_opp_table (dev );
763+ if (IS_ERR (opp_table ))
764+ return ERR_CAST (opp_table );
765+
766+ if (index >= opp_table -> path_count )
767+ return ERR_PTR (- EINVAL );
768+
769+ mutex_lock (& opp_table -> lock );
770+
771+ list_for_each_entry (temp_opp , & opp_table -> opp_list , node ) {
772+ if (temp_opp -> available && temp_opp -> bandwidth ) {
773+ if (temp_opp -> bandwidth [index ].peak >= * bw ) {
774+ opp = temp_opp ;
775+ * bw = opp -> bandwidth [index ].peak ;
776+
777+ /* Increment the reference count of OPP */
778+ dev_pm_opp_get (opp );
779+ break ;
780+ }
781+ }
782+ }
783+
784+ mutex_unlock (& opp_table -> lock );
785+ dev_pm_opp_put_opp_table (opp_table );
786+
787+ return opp ;
788+ }
789+ EXPORT_SYMBOL_GPL (dev_pm_opp_find_bw_ceil );
790+
791+ /**
792+ * dev_pm_opp_find_bw_floor() - Search for a rounded floor bandwidth
793+ * @dev: device for which we do this operation
794+ * @freq: start bandwidth
795+ * @index: which bandwidth to compare, in case of OPPs with several values
796+ *
797+ * Search for the matching floor *available* OPP from a starting bandwidth
798+ * for a device.
799+ *
800+ * Return: matching *opp and refreshes *bw accordingly, else returns
801+ * ERR_PTR in case of error and should be handled using IS_ERR. Error return
802+ * values can be:
803+ * EINVAL: for bad pointer
804+ * ERANGE: no match found for search
805+ * ENODEV: if device not found in list of registered devices
806+ *
807+ * The callers are required to call dev_pm_opp_put() for the returned OPP after
808+ * use.
809+ */
810+ struct dev_pm_opp * dev_pm_opp_find_bw_floor (struct device * dev ,
811+ unsigned int * bw , int index )
812+ {
813+ struct opp_table * opp_table ;
814+ struct dev_pm_opp * temp_opp , * opp = ERR_PTR (- ERANGE );
815+
816+ if (!dev || !bw ) {
817+ dev_err (dev , "%s: Invalid argument bw=%p\n" , __func__ , bw );
818+ return ERR_PTR (- EINVAL );
819+ }
820+
821+ opp_table = _find_opp_table (dev );
822+ if (IS_ERR (opp_table ))
823+ return ERR_CAST (opp_table );
824+
825+ if (index >= opp_table -> path_count )
826+ return ERR_PTR (- EINVAL );
827+
828+ mutex_lock (& opp_table -> lock );
829+
830+ list_for_each_entry (temp_opp , & opp_table -> opp_list , node ) {
831+ if (temp_opp -> available && temp_opp -> bandwidth ) {
832+ /* go to the next node, before choosing prev */
833+ if (temp_opp -> bandwidth [index ].peak > * bw )
834+ break ;
835+ opp = temp_opp ;
836+ }
837+ }
838+
839+ /* Increment the reference count of OPP */
840+ if (!IS_ERR (opp ))
841+ dev_pm_opp_get (opp );
842+ mutex_unlock (& opp_table -> lock );
843+ dev_pm_opp_put_opp_table (opp_table );
844+
845+ if (!IS_ERR (opp ))
846+ * bw = opp -> bandwidth [index ].peak ;
847+
848+ return opp ;
849+ }
850+ EXPORT_SYMBOL_GPL (dev_pm_opp_find_bw_floor );
851+
732852static int _set_opp_voltage (struct device * dev , struct regulator * reg ,
733853 struct dev_pm_opp_supply * supply )
734854{
0 commit comments