@@ -101,11 +101,55 @@ struct opp_table *_find_opp_table(struct device *dev)
101
101
* representation in the OPP table and manage the clock configuration themselves
102
102
* in an platform specific way.
103
103
*/
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 )
105
106
{
106
107
return !WARN_ON (opp_table -> clk_count > 1 );
107
108
}
108
109
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
+
109
153
/**
110
154
* dev_pm_opp_get_voltage() - Gets the voltage corresponding to an opp
111
155
* @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,
499
543
unsigned long (* read )(struct dev_pm_opp * opp , int index ),
500
544
bool (* compare )(struct dev_pm_opp * * opp , struct dev_pm_opp * temp_opp ,
501
545
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 ))
503
547
{
504
548
struct dev_pm_opp * temp_opp , * opp = ERR_PTR (- ERANGE );
505
549
506
550
/* Assert that the requirement is met */
507
- if (assert && !assert (opp_table ))
551
+ if (assert && !assert (opp_table , index ))
508
552
return ERR_PTR (- EINVAL );
509
553
510
554
mutex_lock (& opp_table -> lock );
@@ -532,7 +576,7 @@ _find_key(struct device *dev, unsigned long *key, int index, bool available,
532
576
unsigned long (* read )(struct dev_pm_opp * opp , int index ),
533
577
bool (* compare )(struct dev_pm_opp * * opp , struct dev_pm_opp * temp_opp ,
534
578
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 ))
536
580
{
537
581
struct opp_table * opp_table ;
538
582
struct dev_pm_opp * opp ;
@@ -555,7 +599,7 @@ _find_key(struct device *dev, unsigned long *key, int index, bool available,
555
599
static struct dev_pm_opp * _find_key_exact (struct device * dev ,
556
600
unsigned long key , int index , bool available ,
557
601
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 ))
559
603
{
560
604
/*
561
605
* 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,
568
612
static struct dev_pm_opp * _opp_table_find_key_ceil (struct opp_table * opp_table ,
569
613
unsigned long * key , int index , bool available ,
570
614
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 ))
572
616
{
573
617
return _opp_table_find_key (opp_table , key , index , available , read ,
574
618
_compare_ceil , assert );
@@ -577,7 +621,7 @@ static struct dev_pm_opp *_opp_table_find_key_ceil(struct opp_table *opp_table,
577
621
static struct dev_pm_opp * _find_key_ceil (struct device * dev , unsigned long * key ,
578
622
int index , bool available ,
579
623
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 ))
581
625
{
582
626
return _find_key (dev , key , index , available , read , _compare_ceil ,
583
627
assert );
@@ -586,7 +630,7 @@ static struct dev_pm_opp *_find_key_ceil(struct device *dev, unsigned long *key,
586
630
static struct dev_pm_opp * _find_key_floor (struct device * dev ,
587
631
unsigned long * key , int index , bool available ,
588
632
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 ))
590
634
{
591
635
return _find_key (dev , key , index , available , read , _compare_floor ,
592
636
assert );
@@ -647,7 +691,8 @@ struct dev_pm_opp *
647
691
dev_pm_opp_find_freq_exact_indexed (struct device * dev , unsigned long freq ,
648
692
u32 index , bool available )
649
693
{
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 );
651
696
}
652
697
EXPORT_SYMBOL_GPL (dev_pm_opp_find_freq_exact_indexed );
653
698
@@ -707,7 +752,8 @@ struct dev_pm_opp *
707
752
dev_pm_opp_find_freq_ceil_indexed (struct device * dev , unsigned long * freq ,
708
753
u32 index )
709
754
{
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 );
711
757
}
712
758
EXPORT_SYMBOL_GPL (dev_pm_opp_find_freq_ceil_indexed );
713
759
@@ -760,7 +806,7 @@ struct dev_pm_opp *
760
806
dev_pm_opp_find_freq_floor_indexed (struct device * dev , unsigned long * freq ,
761
807
u32 index )
762
808
{
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 );
764
810
}
765
811
EXPORT_SYMBOL_GPL (dev_pm_opp_find_freq_floor_indexed );
766
812
@@ -878,7 +924,8 @@ struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev, unsigned int *bw,
878
924
unsigned long temp = * bw ;
879
925
struct dev_pm_opp * opp ;
880
926
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 );
882
929
* bw = temp ;
883
930
return opp ;
884
931
}
@@ -909,7 +956,8 @@ struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev,
909
956
unsigned long temp = * bw ;
910
957
struct dev_pm_opp * opp ;
911
958
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 );
913
961
* bw = temp ;
914
962
return opp ;
915
963
}
@@ -1480,11 +1528,6 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index)
1480
1528
return ERR_PTR (ret );
1481
1529
}
1482
1530
1483
- void _get_opp_table_kref (struct opp_table * opp_table )
1484
- {
1485
- kref_get (& opp_table -> kref );
1486
- }
1487
-
1488
1531
static struct opp_table * _update_opp_table_clk (struct device * dev ,
1489
1532
struct opp_table * opp_table ,
1490
1533
bool getclk )
@@ -1645,6 +1688,17 @@ static void _opp_table_kref_release(struct kref *kref)
1645
1688
kfree (opp_table );
1646
1689
}
1647
1690
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
+
1648
1702
void dev_pm_opp_put_opp_table (struct opp_table * opp_table )
1649
1703
{
1650
1704
kref_put_mutex (& opp_table -> kref , _opp_table_kref_release ,
@@ -1679,6 +1733,7 @@ void dev_pm_opp_get(struct dev_pm_opp *opp)
1679
1733
{
1680
1734
kref_get (& opp -> kref );
1681
1735
}
1736
+ EXPORT_SYMBOL_GPL (dev_pm_opp_get );
1682
1737
1683
1738
void dev_pm_opp_put (struct dev_pm_opp * opp )
1684
1739
{
@@ -1702,7 +1757,7 @@ void dev_pm_opp_remove(struct device *dev, unsigned long freq)
1702
1757
if (IS_ERR (opp_table ))
1703
1758
return ;
1704
1759
1705
- if (!assert_single_clk (opp_table ))
1760
+ if (!assert_single_clk (opp_table , 0 ))
1706
1761
goto put_table ;
1707
1762
1708
1763
mutex_lock (& opp_table -> lock );
@@ -2054,7 +2109,7 @@ int _opp_add_v1(struct opp_table *opp_table, struct device *dev,
2054
2109
unsigned long tol , u_volt = data -> u_volt ;
2055
2110
int ret ;
2056
2111
2057
- if (!assert_single_clk (opp_table ))
2112
+ if (!assert_single_clk (opp_table , 0 ))
2058
2113
return - EINVAL ;
2059
2114
2060
2115
new_opp = _opp_allocate (opp_table );
@@ -2810,7 +2865,7 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
2810
2865
return r ;
2811
2866
}
2812
2867
2813
- if (!assert_single_clk (opp_table )) {
2868
+ if (!assert_single_clk (opp_table , 0 )) {
2814
2869
r = - EINVAL ;
2815
2870
goto put_table ;
2816
2871
}
@@ -2886,7 +2941,7 @@ int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
2886
2941
return r ;
2887
2942
}
2888
2943
2889
- if (!assert_single_clk (opp_table )) {
2944
+ if (!assert_single_clk (opp_table , 0 )) {
2890
2945
r = - EINVAL ;
2891
2946
goto put_table ;
2892
2947
}
0 commit comments