@@ -101,11 +101,55 @@ struct opp_table *_find_opp_table(struct device *dev)
101101 * representation in the OPP table and manage the clock configuration themselves
102102 * in an platform specific way.
103103 */
104- static bool assert_single_clk (struct opp_table * opp_table )
104+ static bool assert_single_clk (struct opp_table * opp_table ,
105+ unsigned int __always_unused index )
105106{
106107 return !WARN_ON (opp_table -> clk_count > 1 );
107108}
108109
110+ /*
111+ * Returns true if clock table is large enough to contain the clock index.
112+ */
113+ static bool assert_clk_index (struct opp_table * opp_table ,
114+ unsigned int index )
115+ {
116+ return opp_table -> clk_count > index ;
117+ }
118+
119+ /*
120+ * Returns true if bandwidth table is large enough to contain the bandwidth index.
121+ */
122+ static bool assert_bandwidth_index (struct opp_table * opp_table ,
123+ unsigned int index )
124+ {
125+ return opp_table -> path_count > index ;
126+ }
127+
128+ /**
129+ * dev_pm_opp_get_bw() - Gets the bandwidth corresponding to an opp
130+ * @opp: opp for which bandwidth has to be returned for
131+ * @peak: select peak or average bandwidth
132+ * @index: bandwidth index
133+ *
134+ * Return: bandwidth in kBps, else return 0
135+ */
136+ unsigned long dev_pm_opp_get_bw (struct dev_pm_opp * opp , bool peak , int index )
137+ {
138+ if (IS_ERR_OR_NULL (opp )) {
139+ pr_err ("%s: Invalid parameters\n" , __func__ );
140+ return 0 ;
141+ }
142+
143+ if (index >= opp -> opp_table -> path_count )
144+ return 0 ;
145+
146+ if (!opp -> bandwidth )
147+ return 0 ;
148+
149+ return peak ? opp -> bandwidth [index ].peak : opp -> bandwidth [index ].avg ;
150+ }
151+ EXPORT_SYMBOL_GPL (dev_pm_opp_get_bw );
152+
109153/**
110154 * dev_pm_opp_get_voltage() - Gets the voltage corresponding to an opp
111155 * @opp: opp for which voltage has to be returned for
@@ -499,12 +543,12 @@ static struct dev_pm_opp *_opp_table_find_key(struct opp_table *opp_table,
499543 unsigned long (* read )(struct dev_pm_opp * opp , int index ),
500544 bool (* compare )(struct dev_pm_opp * * opp , struct dev_pm_opp * temp_opp ,
501545 unsigned long opp_key , unsigned long key ),
502- bool (* assert )(struct opp_table * opp_table ))
546+ bool (* assert )(struct opp_table * opp_table , unsigned int index ))
503547{
504548 struct dev_pm_opp * temp_opp , * opp = ERR_PTR (- ERANGE );
505549
506550 /* Assert that the requirement is met */
507- if (assert && !assert (opp_table ))
551+ if (assert && !assert (opp_table , index ))
508552 return ERR_PTR (- EINVAL );
509553
510554 mutex_lock (& opp_table -> lock );
@@ -532,7 +576,7 @@ _find_key(struct device *dev, unsigned long *key, int index, bool available,
532576 unsigned long (* read )(struct dev_pm_opp * opp , int index ),
533577 bool (* compare )(struct dev_pm_opp * * opp , struct dev_pm_opp * temp_opp ,
534578 unsigned long opp_key , unsigned long key ),
535- bool (* assert )(struct opp_table * opp_table ))
579+ bool (* assert )(struct opp_table * opp_table , unsigned int index ))
536580{
537581 struct opp_table * opp_table ;
538582 struct dev_pm_opp * opp ;
@@ -555,7 +599,7 @@ _find_key(struct device *dev, unsigned long *key, int index, bool available,
555599static struct dev_pm_opp * _find_key_exact (struct device * dev ,
556600 unsigned long key , int index , bool available ,
557601 unsigned long (* read )(struct dev_pm_opp * opp , int index ),
558- bool (* assert )(struct opp_table * opp_table ))
602+ bool (* assert )(struct opp_table * opp_table , unsigned int index ))
559603{
560604 /*
561605 * The value of key will be updated here, but will be ignored as the
@@ -568,7 +612,7 @@ static struct dev_pm_opp *_find_key_exact(struct device *dev,
568612static struct dev_pm_opp * _opp_table_find_key_ceil (struct opp_table * opp_table ,
569613 unsigned long * key , int index , bool available ,
570614 unsigned long (* read )(struct dev_pm_opp * opp , int index ),
571- bool (* assert )(struct opp_table * opp_table ))
615+ bool (* assert )(struct opp_table * opp_table , unsigned int index ))
572616{
573617 return _opp_table_find_key (opp_table , key , index , available , read ,
574618 _compare_ceil , assert );
@@ -577,7 +621,7 @@ static struct dev_pm_opp *_opp_table_find_key_ceil(struct opp_table *opp_table,
577621static struct dev_pm_opp * _find_key_ceil (struct device * dev , unsigned long * key ,
578622 int index , bool available ,
579623 unsigned long (* read )(struct dev_pm_opp * opp , int index ),
580- bool (* assert )(struct opp_table * opp_table ))
624+ bool (* assert )(struct opp_table * opp_table , unsigned int index ))
581625{
582626 return _find_key (dev , key , index , available , read , _compare_ceil ,
583627 assert );
@@ -586,7 +630,7 @@ static struct dev_pm_opp *_find_key_ceil(struct device *dev, unsigned long *key,
586630static struct dev_pm_opp * _find_key_floor (struct device * dev ,
587631 unsigned long * key , int index , bool available ,
588632 unsigned long (* read )(struct dev_pm_opp * opp , int index ),
589- bool (* assert )(struct opp_table * opp_table ))
633+ bool (* assert )(struct opp_table * opp_table , unsigned int index ))
590634{
591635 return _find_key (dev , key , index , available , read , _compare_floor ,
592636 assert );
@@ -647,7 +691,8 @@ struct dev_pm_opp *
647691dev_pm_opp_find_freq_exact_indexed (struct device * dev , unsigned long freq ,
648692 u32 index , bool available )
649693{
650- return _find_key_exact (dev , freq , index , available , _read_freq , NULL );
694+ return _find_key_exact (dev , freq , index , available , _read_freq ,
695+ assert_clk_index );
651696}
652697EXPORT_SYMBOL_GPL (dev_pm_opp_find_freq_exact_indexed );
653698
@@ -707,7 +752,8 @@ struct dev_pm_opp *
707752dev_pm_opp_find_freq_ceil_indexed (struct device * dev , unsigned long * freq ,
708753 u32 index )
709754{
710- return _find_key_ceil (dev , freq , index , true, _read_freq , NULL );
755+ return _find_key_ceil (dev , freq , index , true, _read_freq ,
756+ assert_clk_index );
711757}
712758EXPORT_SYMBOL_GPL (dev_pm_opp_find_freq_ceil_indexed );
713759
@@ -760,7 +806,7 @@ struct dev_pm_opp *
760806dev_pm_opp_find_freq_floor_indexed (struct device * dev , unsigned long * freq ,
761807 u32 index )
762808{
763- return _find_key_floor (dev , freq , index , true, _read_freq , NULL );
809+ return _find_key_floor (dev , freq , index , true, _read_freq , assert_clk_index );
764810}
765811EXPORT_SYMBOL_GPL (dev_pm_opp_find_freq_floor_indexed );
766812
@@ -878,7 +924,8 @@ struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev, unsigned int *bw,
878924 unsigned long temp = * bw ;
879925 struct dev_pm_opp * opp ;
880926
881- opp = _find_key_ceil (dev , & temp , index , true, _read_bw , NULL );
927+ opp = _find_key_ceil (dev , & temp , index , true, _read_bw ,
928+ assert_bandwidth_index );
882929 * bw = temp ;
883930 return opp ;
884931}
@@ -909,7 +956,8 @@ struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev,
909956 unsigned long temp = * bw ;
910957 struct dev_pm_opp * opp ;
911958
912- opp = _find_key_floor (dev , & temp , index , true, _read_bw , NULL );
959+ opp = _find_key_floor (dev , & temp , index , true, _read_bw ,
960+ assert_bandwidth_index );
913961 * bw = temp ;
914962 return opp ;
915963}
@@ -1480,11 +1528,6 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index)
14801528 return ERR_PTR (ret );
14811529}
14821530
1483- void _get_opp_table_kref (struct opp_table * opp_table )
1484- {
1485- kref_get (& opp_table -> kref );
1486- }
1487-
14881531static struct opp_table * _update_opp_table_clk (struct device * dev ,
14891532 struct opp_table * opp_table ,
14901533 bool getclk )
@@ -1645,6 +1688,17 @@ static void _opp_table_kref_release(struct kref *kref)
16451688 kfree (opp_table );
16461689}
16471690
1691+ void _get_opp_table_kref (struct opp_table * opp_table )
1692+ {
1693+ kref_get (& opp_table -> kref );
1694+ }
1695+
1696+ void dev_pm_opp_get_opp_table_ref (struct opp_table * opp_table )
1697+ {
1698+ _get_opp_table_kref (opp_table );
1699+ }
1700+ EXPORT_SYMBOL_GPL (dev_pm_opp_get_opp_table_ref );
1701+
16481702void dev_pm_opp_put_opp_table (struct opp_table * opp_table )
16491703{
16501704 kref_put_mutex (& opp_table -> kref , _opp_table_kref_release ,
@@ -1679,6 +1733,7 @@ void dev_pm_opp_get(struct dev_pm_opp *opp)
16791733{
16801734 kref_get (& opp -> kref );
16811735}
1736+ EXPORT_SYMBOL_GPL (dev_pm_opp_get );
16821737
16831738void dev_pm_opp_put (struct dev_pm_opp * opp )
16841739{
@@ -1702,7 +1757,7 @@ void dev_pm_opp_remove(struct device *dev, unsigned long freq)
17021757 if (IS_ERR (opp_table ))
17031758 return ;
17041759
1705- if (!assert_single_clk (opp_table ))
1760+ if (!assert_single_clk (opp_table , 0 ))
17061761 goto put_table ;
17071762
17081763 mutex_lock (& opp_table -> lock );
@@ -2054,7 +2109,7 @@ int _opp_add_v1(struct opp_table *opp_table, struct device *dev,
20542109 unsigned long tol , u_volt = data -> u_volt ;
20552110 int ret ;
20562111
2057- if (!assert_single_clk (opp_table ))
2112+ if (!assert_single_clk (opp_table , 0 ))
20582113 return - EINVAL ;
20592114
20602115 new_opp = _opp_allocate (opp_table );
@@ -2810,7 +2865,7 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
28102865 return r ;
28112866 }
28122867
2813- if (!assert_single_clk (opp_table )) {
2868+ if (!assert_single_clk (opp_table , 0 )) {
28142869 r = - EINVAL ;
28152870 goto put_table ;
28162871 }
@@ -2886,7 +2941,7 @@ int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
28862941 return r ;
28872942 }
28882943
2889- if (!assert_single_clk (opp_table )) {
2944+ if (!assert_single_clk (opp_table , 0 )) {
28902945 r = - EINVAL ;
28912946 goto put_table ;
28922947 }
0 commit comments